Migrate @woocommerce/date to TS

This commit is contained in:
Chi-Hsuan Huang 2022-05-19 14:48:32 +08:00
parent 7e49c151b7
commit 172a50cab0
5 changed files with 247 additions and 96 deletions

View File

@ -19,11 +19,13 @@
}, },
"main": "build/index.js", "main": "build/index.js",
"module": "build-module/index.js", "module": "build-module/index.js",
"types": "build-types",
"react-native": "src/index", "react-native": "src/index",
"dependencies": { "dependencies": {
"@wordpress/date": "^4.3.1", "@wordpress/date": "^4.3.1",
"@wordpress/i18n": "^4.3.1", "@wordpress/i18n": "^4.3.1",
"moment": "^2.29.1", "moment": "^2.29.1",
"moment-timezone": "^0.5.34",
"qs": "^6.10.3" "qs": "^6.10.3"
}, },
"devDependencies": { "devDependencies": {

View File

@ -2,23 +2,49 @@
* External dependencies * External dependencies
*/ */
import moment from 'moment'; import moment from 'moment';
import 'moment-timezone';
import { find, memoize } from 'lodash'; import { find, memoize } from 'lodash';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { parse } from 'qs'; import { parse } from 'qs';
export const isoDateFormat = 'YYYY-MM-DD'; type Query = {
[ key: string ]: string | undefined;
};
export const isoDateFormat = 'YYYY-MM-DD';
export const defaultDateTimeFormat = 'YYYY-MM-DDTHH:mm:ss'; export const defaultDateTimeFormat = 'YYYY-MM-DDTHH:mm:ss';
/** /**
* DateValue Object * DateValue Object
* *
* @typedef {Object} DateValue - Describes the date range supplied by the date picker. * @typedef {Object} DateValue - DateValue data about the selected period.
* @property {moment.Moment} primaryStart - Primary start of the date range.
* @property {moment.Moment} primaryEnd - Primary end of the date range.
* @property {moment.Moment} secondaryStart - Secondary start of the date range.
* @property {moment.Moment} secondaryEnd - Secondary End of the date range.
*/
export type DateValue = {
primaryStart: moment.Moment;
primaryEnd: moment.Moment;
secondaryStart: moment.Moment;
secondaryEnd: moment.Moment;
};
/**
* DataPickerOptions Object
*
* @typedef {Object} DataPickerOptions - Describes the date range supplied by the date picker.
* @property {string} label - The translated value of the period. * @property {string} label - The translated value of the period.
* @property {string} range - The human readable value of a date range. * @property {string} range - The human readable value of a date range.
* @property {moment.Moment} after - Start of the date range. * @property {moment.Moment} after - Start of the date range.
* @property {moment.Moment} before - End of the date range. * @property {moment.Moment} before - End of the date range.
*/ */
export type DataPickerOptions = {
label: string;
range: string;
after: moment.Moment;
before: moment.Moment;
};
/** /**
* DateParams Object * DateParams Object
@ -29,6 +55,12 @@ export const defaultDateTimeFormat = 'YYYY-MM-DDTHH:mm:ss';
* @param {moment.Moment|null} after - If the period supplied is "custom", this is the after date * @param {moment.Moment|null} after - If the period supplied is "custom", this is the after date
* @param {moment.Moment|null} before - If the period supplied is "custom", this is the before date * @param {moment.Moment|null} before - If the period supplied is "custom", this is the before date
*/ */
export type DateParams = {
period: string;
compare: string;
after: moment.Moment | null;
before: moment.Moment | null;
};
export const presetValues = [ export const presetValues = [
{ value: 'today', label: __( 'Today', 'woocommerce' ) }, { value: 'today', label: __( 'Today', 'woocommerce' ) },
@ -55,6 +87,9 @@ export const periods = [
}, },
]; ];
const isValidMomentInput = ( input: unknown ): input is moment.MomentInput =>
moment( input as moment.MomentInput ).isValid();
/** /**
* Adds timestamp to a string date. * Adds timestamp to a string date.
* *
@ -62,7 +97,7 @@ export const periods = [
* @param {string} timeOfDay - Either `start`, `now` or `end` of the day. * @param {string} timeOfDay - Either `start`, `now` or `end` of the day.
* @return {string} - String date with timestamp attached. * @return {string} - String date with timestamp attached.
*/ */
export const appendTimestamp = ( date, timeOfDay ) => { export const appendTimestamp = ( date: moment.Moment, timeOfDay: string ) => {
if ( timeOfDay === 'start' ) { if ( timeOfDay === 'start' ) {
return date.startOf( 'day' ).format( defaultDateTimeFormat ); return date.startOf( 'day' ).format( defaultDateTimeFormat );
} }
@ -84,9 +119,9 @@ export const appendTimestamp = ( date, timeOfDay ) => {
* *
* @param {string} format - localized date string format * @param {string} format - localized date string format
* @param {string} str - date string * @param {string} str - date string
* @return {Object|null} - Moment object representing given string * @return {moment.Moment|null} - Moment object representing given string
*/ */
export function toMoment( format, str ) { export function toMoment( format: string, str: string ) {
if ( moment.isMoment( str ) ) { if ( moment.isMoment( str ) ) {
return str.isValid() ? str : null; return str.isValid() ? str : null;
} }
@ -100,11 +135,11 @@ export function toMoment( format, str ) {
/** /**
* Given two dates, derive a string representation * Given two dates, derive a string representation
* *
* @param {Object} after - start date * @param {moment.Moment} after - start date
* @param {Object} before - end date * @param {moment.Moment} before - end date
* @return {string} - text value for the supplied date range * @return {string} - text value for the supplied date range
*/ */
export function getRangeLabel( after, before ) { export function getRangeLabel( after: moment.Moment, before: moment.Moment ) {
const isSameYear = after.year() === before.year(); const isSameYear = after.year() === before.year();
const isSameMonth = isSameYear && after.month() === before.month(); const isSameMonth = isSameYear && after.month() === before.month();
const isSameDay = const isSameDay =
@ -117,7 +152,10 @@ export function getRangeLabel( after, before ) {
const afterDate = after.date(); const afterDate = after.date();
return after return after
.format( fullDateFormat ) .format( fullDateFormat )
.replace( afterDate, `${ afterDate } - ${ before.date() }` ); .replace(
String( afterDate ),
`${ afterDate } - ${ before.date() }`
);
} else if ( isSameYear ) { } else if ( isSameYear ) {
const monthDayFormat = __( 'MMM D', 'woocommerce' ); const monthDayFormat = __( 'MMM D', 'woocommerce' );
return `${ after.format( monthDayFormat ) } - ${ before.format( return `${ after.format( monthDayFormat ) } - ${ before.format(
@ -149,11 +187,14 @@ export function getStoreTimeZoneMoment() {
/** /**
* Get a DateValue object for a period prior to the current period. * Get a DateValue object for a period prior to the current period.
* *
* @param {string} period - the chosen period * @param {moment.DurationInputArg2} period - the chosen period
* @param {string} compare - `previous_period` or `previous_year` * @param {string} compare - `previous_period` or `previous_year`
* @return {DateValue} - DateValue data about the selected period * @return {DateValue} - DateValue data about the selected period
*/ */
export function getLastPeriod( period, compare ) { export function getLastPeriod(
period: moment.DurationInputArg2,
compare: string
) {
const primaryStart = getStoreTimeZoneMoment() const primaryStart = getStoreTimeZoneMoment()
.startOf( period ) .startOf( period )
.subtract( 1, period ); .subtract( 1, period );
@ -198,11 +239,14 @@ export function getLastPeriod( period, compare ) {
* Get a DateValue object for a curent period. The period begins on the first day of the period, * Get a DateValue object for a curent period. The period begins on the first day of the period,
* and ends on the current day. * and ends on the current day.
* *
* @param {string} period - the chosen period * @param {moment.DurationInputArg2} period - the chosen period
* @param {string} compare - `previous_period` or `previous_year` * @param {string} compare - `previous_period` or `previous_year`
* @return {DateValue} - DateValue data about the selected period * @return {DateValue} - DateValue data about the selected period
*/ */
export function getCurrentPeriod( period, compare ) { export function getCurrentPeriod(
period: moment.DurationInputArg2,
compare: string
) {
const primaryStart = getStoreTimeZoneMoment().startOf( period ); const primaryStart = getStoreTimeZoneMoment().startOf( period );
const primaryEnd = getStoreTimeZoneMoment(); const primaryEnd = getStoreTimeZoneMoment();
@ -233,13 +277,17 @@ export function getCurrentPeriod( period, compare ) {
* Get a DateValue object for a period described by a period, compare value, and start/end * Get a DateValue object for a period described by a period, compare value, and start/end
* dates, for custom dates. * dates, for custom dates.
* *
* @param {string} period - the chosen period * @param {string} period - the chosen period
* @param {string} compare - `previous_period` or `previous_year` * @param {string} compare - `previous_period` or `previous_year`
* @param {Object} [after] - after date if custom period * @param {moment.Moment|null} [after] - after date if custom period
* @param {Object} [before] - before date if custom period * @param {moment.Moment|null} [before] - before date if custom period
* @return {DateValue} - DateValue data about the selected period * @return {DateValue} - DateValue data about the selected period
*/ */
const getDateValue = memoize( const getDateValue = memoize<
(
...args: [ string, string, moment.Moment | null, moment.Moment | null ]
) => DateValue | undefined
>(
( period, compare, after, before ) => { ( period, compare, after, before ) => {
switch ( period ) { switch ( period ) {
case 'today': case 'today':
@ -263,6 +311,12 @@ const getDateValue = memoize(
case 'last_year': case 'last_year':
return getLastPeriod( 'year', compare ); return getLastPeriod( 'year', compare );
case 'custom': case 'custom':
if ( ! after || ! before ) {
throw Error(
'Custom date range requires both after and before dates.'
);
}
const difference = before.diff( after, 'days' ); const difference = before.diff( after, 'days' );
if ( compare === 'previous_period' ) { if ( compare === 'previous_period' ) {
const secondaryEnd = after.clone().subtract( 1, 'days' ); const secondaryEnd = after.clone().subtract( 1, 'days' );
@ -296,15 +350,31 @@ const getDateValue = memoize(
/** /**
* Memoized internal logic of getDateParamsFromQuery(). * Memoized internal logic of getDateParamsFromQuery().
* *
* @param {string} period - period value, ie `last_week` * @param {string|undefined} period - period value, ie `last_week`
* @param {string} compare - compare value, ie `previous_year` * @param {string|undefined} compare - compare value, ie `previous_year`
* @param {string} after - date in iso date format, ie `2018-07-03` * @param {string|undefined} after - date in iso date format, ie `2018-07-03`
* @param {string} before - date in iso date format, ie `2018-07-03` * @param {string|undefined} before - date in iso date format, ie `2018-07-03`
* @param {string} defaultDateRange - the store's default date range * @param {string} defaultDateRange - the store's default date range
* @return {Object} - date parameters derived from query parameters with added defaults * @return {DateParams} - date parameters derived from query parameters with added defaults
*/ */
const getDateParamsFromQueryMemoized = memoize( const getDateParamsFromQueryMemoized = memoize<
( period, compare, after, before, defaultDateRange ) => { (
...args: [
string | undefined,
string | undefined,
string | undefined,
string | undefined,
string
]
) => DateParams
>(
(
period: string | undefined,
compare: string | undefined,
after: string | undefined,
before: string | undefined,
defaultDateRange: string
) => {
if ( period && compare ) { if ( period && compare ) {
return { return {
period, period,
@ -317,13 +387,30 @@ const getDateParamsFromQueryMemoized = memoize(
defaultDateRange.replace( /&amp;/g, '&' ) defaultDateRange.replace( /&amp;/g, '&' )
); );
if ( typeof queryDefaults.period !== 'string' ) {
throw Error(
`Unexpected default period type ${ queryDefaults.period }`
);
}
if ( typeof queryDefaults.compare !== 'string' ) {
throw Error(
`Unexpected default compare type ${ queryDefaults.compare }`
);
}
return { return {
period: queryDefaults.period, period: queryDefaults.period,
compare: queryDefaults.compare, compare: queryDefaults.compare,
after: queryDefaults.after ? moment( queryDefaults.after ) : null, after:
before: queryDefaults.before queryDefaults.after && isValidMomentInput( queryDefaults.after )
? moment( queryDefaults.before ) ? moment( queryDefaults.after )
: null, : null,
before:
queryDefaults.before &&
isValidMomentInput( queryDefaults.before )
? moment( queryDefaults.before )
: null,
}; };
}, },
( period, compare, after, before, defaultDateRange ) => ( period, compare, after, before, defaultDateRange ) =>
@ -342,7 +429,7 @@ const getDateParamsFromQueryMemoized = memoize(
* @return {DateParams} - date parameters derived from query parameters with added defaults * @return {DateParams} - date parameters derived from query parameters with added defaults
*/ */
export const getDateParamsFromQuery = ( export const getDateParamsFromQuery = (
query, query: Query,
defaultDateRange = 'period=month&compare=previous_year' defaultDateRange = 'period=month&compare=previous_year'
) => { ) => {
const { period, compare, after, before } = query; const { period, compare, after, before } = query;
@ -359,15 +446,29 @@ export const getDateParamsFromQuery = (
/** /**
* Memoized internal logic of getCurrentDates(). * Memoized internal logic of getCurrentDates().
* *
* @param {string} period - period value, ie `last_week` * @param {string|undefined} period - period value, ie `last_week`
* @param {string} compare - compare value, ie `previous_year` * @param {string|undefined} compare - compare value, ie `previous_year`
* @param {Object} primaryStart - primary query start DateTime, in Moment instance. * @param {Object} primaryStart - primary query start DateTime, in Moment instance.
* @param {Object} primaryEnd - primary query start DateTime, in Moment instance. * @param {Object} primaryEnd - primary query start DateTime, in Moment instance.
* @param {Object} secondaryStart - primary query start DateTime, in Moment instance. * @param {Object} secondaryStart - secondary query start DateTime, in Moment instance.
* @param {Object} secondaryEnd - primary query start DateTime, in Moment instance. * @param {Object} secondaryEnd - secondary query start DateTime, in Moment instance.
* @return {{primary: DateValue, secondary: DateValue}} - Primary and secondary DateValue objects * @return {{primary: DataPickerOptions, secondary: DataPickerOptions}} - Primary and secondary DataPickerOptions objects
*/ */
const getCurrentDatesMemoized = memoize( const getCurrentDatesMemoized = memoize<
(
...args: [
string,
string,
moment.Moment,
moment.Moment,
moment.Moment,
moment.Moment
]
) => {
primary: DataPickerOptions;
secondary: DataPickerOptions;
}
>(
( (
period, period,
compare, compare,
@ -377,14 +478,21 @@ const getCurrentDatesMemoized = memoize(
secondaryEnd secondaryEnd
) => ( { ) => ( {
primary: { primary: {
label: find( presetValues, ( item ) => item.value === period ) label: (
.label, find( presetValues, ( item ) => item.value === period ) || {
label: '',
}
).label,
range: getRangeLabel( primaryStart, primaryEnd ), range: getRangeLabel( primaryStart, primaryEnd ),
after: primaryStart, after: primaryStart,
before: primaryEnd, before: primaryEnd,
}, },
secondary: { secondary: {
label: find( periods, ( item ) => item.value === compare ).label, label: (
find( periods, ( item ) => item.value === compare ) || {
label: '',
}
).label,
range: getRangeLabel( secondaryStart, secondaryEnd ), range: getRangeLabel( secondaryStart, secondaryEnd ),
after: secondaryStart, after: secondaryStart,
before: secondaryEnd, before: secondaryEnd,
@ -417,22 +525,29 @@ const getCurrentDatesMemoized = memoize(
* @param {string} query.after - date in iso date format, ie `2018-07-03` * @param {string} query.after - date in iso date format, ie `2018-07-03`
* @param {string} query.before - date in iso date format, ie `2018-07-03` * @param {string} query.before - date in iso date format, ie `2018-07-03`
* @param {string} defaultDateRange - the store's default date range * @param {string} defaultDateRange - the store's default date range
* @return {{primary: DateValue, secondary: DateValue}} - Primary and secondary DateValue objects * @return {{primary: DataPickerOptions, secondary: DataPickerOptions}} - Primary and secondary DataPickerOptions objects
*/ */
export const getCurrentDates = ( export const getCurrentDates = (
query, query: Query,
defaultDateRange = 'period=month&compare=previous_year' defaultDateRange = 'period=month&compare=previous_year'
) => { ) => {
const { period, compare, after, before } = getDateParamsFromQuery( const { period, compare, after, before } = getDateParamsFromQuery(
query, query,
defaultDateRange defaultDateRange
); );
const dateValue = getDateValue( period, compare, after, before );
if ( ! dateValue ) {
throw Error( 'Invalid date range' );
}
const { const {
primaryStart, primaryStart,
primaryEnd, primaryEnd,
secondaryStart, secondaryStart,
secondaryEnd, secondaryEnd,
} = getDateValue( period, compare, after, before ); } = dateValue;
return getCurrentDatesMemoized( return getCurrentDatesMemoized(
period, period,
@ -448,10 +563,13 @@ export const getCurrentDates = (
* Calculates the date difference between two dates. Used in calculating a matching date for previous period. * Calculates the date difference between two dates. Used in calculating a matching date for previous period.
* *
* @param {string} date - Date to compare * @param {string} date - Date to compare
* @param {string} date2 - Seconary date to compare * @param {string} date2 - Secondary date to compare
* @return {number} - Difference in days. * @return {number} - Difference in days.
*/ */
export const getDateDifferenceInDays = ( date, date2 ) => { export const getDateDifferenceInDays = (
date: moment.MomentInput,
date2: moment.MomentInput
) => {
const _date = moment( date ); const _date = moment( date );
const _date2 = moment( date2 ); const _date2 = moment( date2 );
return _date.diff( _date2, 'days' ); return _date.diff( _date2, 'days' );
@ -460,14 +578,20 @@ export const getDateDifferenceInDays = ( date, date2 ) => {
/** /**
* Get the previous date for either the previous period of year. * Get the previous date for either the previous period of year.
* *
* @param {string} date - Base date * @param {string} date - Base date
* @param {string} date1 - primary start * @param {string} date1 - primary start
* @param {string} date2 - secondary start * @param {string} date2 - secondary start
* @param {string} compare - `previous_period` or `previous_year` * @param {string} compare - `previous_period` or `previous_year`
* @param {string} interval - interval * @param {moment.unitOfTime.Diff} interval - interval
* @return {Object} - Calculated date * @return {Object} - Calculated date
*/ */
export const getPreviousDate = ( date, date1, date2, compare, interval ) => { export const getPreviousDate = (
date: string,
date1: string,
date2: string,
compare: string,
interval: moment.unitOfTime.Diff | moment.DurationInputArg2
) => {
const dateMoment = moment( date ); const dateMoment = moment( date );
if ( compare === 'previous_year' ) { if ( compare === 'previous_year' ) {
@ -484,12 +608,12 @@ export const getPreviousDate = ( date, date1, date2, compare, interval ) => {
/** /**
* Returns the allowed selectable intervals for a specific query. * Returns the allowed selectable intervals for a specific query.
* *
* @param {Object} query Current query * @param {Query} query Current query
* @param {string} defaultDateRange - the store's default date range * @param {string} defaultDateRange - the store's default date range
* @return {Array} Array containing allowed intervals. * @return {Array} Array containing allowed intervals.
*/ */
export function getAllowedIntervalsForQuery( export function getAllowedIntervalsForQuery(
query, query: Query,
defaultDateRange = 'period=&compare=previous_year' defaultDateRange = 'period=&compare=previous_year'
) { ) {
const { period } = getDateParamsFromQuery( query, defaultDateRange ); const { period } = getDateParamsFromQuery( query, defaultDateRange );
@ -546,12 +670,12 @@ export function getAllowedIntervalsForQuery(
/** /**
* Returns the current interval to use. * Returns the current interval to use.
* *
* @param {Object} query Current query * @param {Query} query Current query
* @param {string} defaultDateRange - the store's default date range * @param {string} defaultDateRange - the store's default date range
* @return {string} Current interval. * @return {string} Current interval.
*/ */
export function getIntervalForQuery( export function getIntervalForQuery(
query, query: Query,
defaultDateRange = 'period=&compare=previous_year' defaultDateRange = 'period=&compare=previous_year'
) { ) {
const allowed = getAllowedIntervalsForQuery( query, defaultDateRange ); const allowed = getAllowedIntervalsForQuery( query, defaultDateRange );
@ -567,11 +691,11 @@ export function getIntervalForQuery(
/** /**
* Returns the current chart type to use. * Returns the current chart type to use.
* *
* @param {Object} query Current query * @param {Query} query Current query
* @param {string} query.chartType * @param {string} query.chartType
* @return {string} Current chart type. * @return {string} Current chart type.
*/ */
export function getChartTypeForQuery( { chartType } ) { export function getChartTypeForQuery( { chartType = '' }: Query ) {
if ( [ 'line', 'bar' ].includes( chartType ) ) { if ( [ 'line', 'bar' ].includes( chartType ) ) {
return chartType; return chartType;
} }
@ -582,30 +706,6 @@ export const dayTicksThreshold = 63;
export const weekTicksThreshold = 9; export const weekTicksThreshold = 9;
export const defaultTableDateFormat = 'm/d/Y'; export const defaultTableDateFormat = 'm/d/Y';
/**
* Returns date formats for the current interval.
*
* @param {string} interval Interval to get date formats for.
* @param {number} [ticks] Number of ticks the axis will have.
* @param {Object} [option] Options
* @param {string} [option.type] Date format type, d3 or php, defaults to d3.
* @return {string} Current interval.
*/
export function getDateFormatsForInterval(
interval,
ticks = 0,
option = { type: 'd3' }
) {
switch ( option.type ) {
case 'php':
return getDateFormatsForIntervalPhp( interval, ticks );
case 'd3':
default:
return getDateFormatsForIntervalD3( interval, ticks );
}
}
/** /**
* Returns d3 date formats for the current interval. * Returns d3 date formats for the current interval.
* See https://github.com/d3/d3-time-format for chart formats. * See https://github.com/d3/d3-time-format for chart formats.
@ -614,7 +714,7 @@ export function getDateFormatsForInterval(
* @param {number} [ticks] Number of ticks the axis will have. * @param {number} [ticks] Number of ticks the axis will have.
* @return {string} Current interval. * @return {string} Current interval.
*/ */
export function getDateFormatsForIntervalD3( interval, ticks = 0 ) { export function getDateFormatsForIntervalD3( interval: string, ticks = 0 ) {
let screenReaderFormat = '%B %-d, %Y'; let screenReaderFormat = '%B %-d, %Y';
let tooltipLabelFormat = '%B %-d, %Y'; let tooltipLabelFormat = '%B %-d, %Y';
let xFormat = '%Y-%m-%d'; let xFormat = '%Y-%m-%d';
@ -681,7 +781,7 @@ export function getDateFormatsForIntervalD3( interval, ticks = 0 ) {
* @param {number} [ticks] Number of ticks the axis will have. * @param {number} [ticks] Number of ticks the axis will have.
* @return {string} Current interval. * @return {string} Current interval.
*/ */
export function getDateFormatsForIntervalPhp( interval, ticks = 0 ) { export function getDateFormatsForIntervalPhp( interval: string, ticks = 0 ) {
let screenReaderFormat = 'F j, Y'; let screenReaderFormat = 'F j, Y';
let tooltipLabelFormat = 'F j, Y'; let tooltipLabelFormat = 'F j, Y';
let xFormat = 'Y-m-d'; let xFormat = 'Y-m-d';
@ -745,6 +845,30 @@ export function getDateFormatsForIntervalPhp( interval, ticks = 0 ) {
}; };
} }
/**
* Returns date formats for the current interval.
*
* @param {string} interval Interval to get date formats for.
* @param {number} [ticks] Number of ticks the axis will have.
* @param {Object} [option] Options
* @param {string} [option.type] Date format type, d3 or php, defaults to d3.
* @return {string} Current interval.
*/
export function getDateFormatsForInterval(
interval: string,
ticks = 0,
option = { type: 'd3' }
) {
switch ( option.type ) {
case 'php':
return getDateFormatsForIntervalPhp( interval, ticks );
case 'd3':
default:
return getDateFormatsForIntervalD3( interval, ticks );
}
}
/** /**
* Gutenberg's moment instance is loaded with i18n values, which are * Gutenberg's moment instance is loaded with i18n values, which are
* PHP date formats, ie 'LLL: "F j, Y g:i a"'. Override those with translations * PHP date formats, ie 'LLL: "F j, Y g:i a"'. Override those with translations
@ -754,7 +878,13 @@ export function getDateFormatsForIntervalPhp( interval, ticks = 0 ) {
* @param {string} config.userLocale * @param {string} config.userLocale
* @param {Array} config.weekdaysShort * @param {Array} config.weekdaysShort
*/ */
export function loadLocaleData( { userLocale, weekdaysShort } ) { export function loadLocaleData( {
userLocale,
weekdaysShort,
}: {
userLocale: string;
weekdaysShort: moment.LocaleSpecification[ 'weekdaysMin' ];
} ) {
// Don't update if the wp locale hasn't been set yet, like in unit tests, for instance. // Don't update if the wp locale hasn't been set yet, like in unit tests, for instance.
if ( moment.locale() !== 'en' ) { if ( moment.locale() !== 'en' ) {
moment.updateLocale( userLocale, { moment.updateLocale( userLocale, {
@ -764,6 +894,9 @@ export function loadLocaleData( { userLocale, weekdaysShort } ) {
LLL: __( 'D MMMM YYYY LT', 'woocommerce' ), LLL: __( 'D MMMM YYYY LT', 'woocommerce' ),
LLLL: __( 'dddd, D MMMM YYYY LT', 'woocommerce' ), LLLL: __( 'dddd, D MMMM YYYY LT', 'woocommerce' ),
LT: __( 'HH:mm', 'woocommerce' ), LT: __( 'HH:mm', 'woocommerce' ),
// Set LTS to default LTS locale format because we don't have a specific format for it.
// Reference https://github.com/moment/moment/blob/develop/dist/moment.js
LTS: 'h:mm:ss A',
}, },
weekdaysMin: weekdaysShort, weekdaysMin: weekdaysShort,
} ); } );
@ -794,11 +927,11 @@ export const dateValidationMessages = {
* @return {Object} validatedDate - validated date object * @return {Object} validatedDate - validated date object
*/ */
export function validateDateInputForRange( export function validateDateInputForRange(
type, type: string,
value, value: string,
before, before: moment.MomentInput | null,
after, after: moment.MomentInput | null,
format format: string
) { ) {
const date = toMoment( format, value ); const date = toMoment( format, value );
if ( ! date ) { if ( ! date ) {

View File

@ -2,6 +2,9 @@
"extends": "../tsconfig", "extends": "../tsconfig",
"compilerOptions": { "compilerOptions": {
"rootDir": "src", "rootDir": "src",
"outDir": "build-module" "outDir": "build-module",
"declaration": true,
"declarationMap": true,
"declarationDir": "./build-types"
} }
} }

10
packages/js/date/typings/global.d.ts vendored Normal file
View File

@ -0,0 +1,10 @@
declare global {
interface Window {
wcSettings: {
timeZone?: string;
};
}
}
/*~ If your module exports nothing, you'll need this line. Otherwise, delete it */
export {};

View File

@ -560,6 +560,7 @@ importers:
jest: ^27.5.1 jest: ^27.5.1
jest-cli: ^27.5.1 jest-cli: ^27.5.1
moment: ^2.29.1 moment: ^2.29.1
moment-timezone: ^0.5.34
qs: ^6.10.3 qs: ^6.10.3
rimraf: ^3.0.2 rimraf: ^3.0.2
ts-jest: ^27.1.3 ts-jest: ^27.1.3
@ -568,6 +569,7 @@ importers:
'@wordpress/date': 4.4.1 '@wordpress/date': 4.4.1
'@wordpress/i18n': 4.4.1 '@wordpress/i18n': 4.4.1
moment: 2.29.1 moment: 2.29.1
moment-timezone: 0.5.34
qs: 6.10.3 qs: 6.10.3
devDependencies: devDependencies:
'@babel/core': 7.17.8 '@babel/core': 7.17.8
@ -13713,6 +13715,7 @@ packages:
re-resizable: 4.11.0 re-resizable: 4.11.0
transitivePeerDependencies: transitivePeerDependencies:
- react - react
- react-dom
dev: true dev: true
/@types/wordpress__compose/4.0.1: /@types/wordpress__compose/4.0.1:
@ -18579,7 +18582,7 @@ packages:
dev: true dev: true
/buffer-crc32/0.2.13: /buffer-crc32/0.2.13:
resolution: {integrity: sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=} resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
/buffer-fill/1.0.0: /buffer-fill/1.0.0:
resolution: {integrity: sha1-+PeLdniYiO858gXNY39o5wISKyw=} resolution: {integrity: sha1-+PeLdniYiO858gXNY39o5wISKyw=}