@wordpress/components
Version:
UI components for WordPress.
154 lines (151 loc) • 4.73 kB
JavaScript
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { useMemo } from '@wordpress/element';
/**
* Internal dependencies
*/
function isLocaleRTL(localeCode) {
const localeObj = new Intl.Locale(localeCode);
if ('getTextInfo' in localeObj) {
// @ts-expect-error - getTextInfo is not typed yet
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/getTextInfo
return localeObj.getTextInfo().direction === 'rtl';
}
return ['ar',
// Arabic
'he',
// Hebrew
'fa',
// Persian (Farsi)
'ur',
// Urdu
'ps',
// Pashto
'syr',
// Syriac
'dv',
// Divehi
'ku',
// Kurdish (Sorani)
'yi' // Yiddish
].includes(localeObj.language);
}
/**
* Returns localization props for the calendar components.
*
* Notes:
* - the following props should be intended as defaults, and should
* be overridden by consumer props if listed as public props.
* - It is possible for the translated strings to use a different locale
* than the formatted dates and the computed `dir`. This is because the
* translation function doesn't expose the locale used for the translated
* strings, meaning that the dates are formatted using the `locale` prop.
* For a correct localized experience, consumers should make sure that
* translation context and `locale` prop are consistent.
* @param props
* @param props.locale
* @param props.timeZone
* @param props.mode
*/
export const useLocalizationProps = ({
locale,
timeZone,
mode
}) => {
return useMemo(() => {
// ie. April 2025
const monthNameFormatter = new Intl.DateTimeFormat(locale.code, {
year: 'numeric',
month: 'long',
timeZone
});
// ie. M, T, W, T, F, S, S
const weekdayNarrowFormatter = new Intl.DateTimeFormat(locale.code, {
weekday: 'narrow',
timeZone
});
// ie. Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
const weekdayLongFormatter = new Intl.DateTimeFormat(locale.code, {
weekday: 'long',
timeZone
});
// ie. Monday, April 29, 2025
const fullDateFormatter = new Intl.DateTimeFormat(locale.code, {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone
});
// Note: the following props should be intended as defaults, and should
// be overridden by consumer props if listed as public props.
return {
'aria-label': mode === 'single' ? __('Date calendar') : __('Date range calendar'),
labels: {
/**
* The label for the month grid.
* @param date
*/
labelGrid: date => monthNameFormatter.format(date),
/**
* The label for the gridcell, when the calendar is not interactive.
* @param date
* @param modifiers
*/
labelGridcell: (date, modifiers) => {
const formattedDate = fullDateFormatter.format(date);
let label = formattedDate;
if (modifiers?.today) {
label = sprintf(
// translators: %s is the full date (e.g. "Monday, April 29, 2025")
__('Today, %s'), formattedDate);
}
return label;
},
/** The label for the "next month" button. */
labelNext: () => __('Go to the Next Month'),
/** The label for the "previous month" button. */
labelPrevious: () => __('Go to the Previous Month'),
/**
* The label for the day button.
* @param date
* @param modifiers
*/
labelDayButton: (date, modifiers) => {
const formattedDate = fullDateFormatter.format(date);
let label = formattedDate;
if (modifiers?.today) {
label = sprintf(
// translators: %s is the full date (e.g. "Monday, April 29, 2025")
__('Today, %s'), formattedDate);
}
if (modifiers?.selected) {
label = sprintf(
// translators: %s is the full date (e.g. "Monday, April 29, 2025")
__('%s, selected'), formattedDate);
}
return label;
},
/**
* The label for the weekday.
* @param date
*/
labelWeekday: date => weekdayLongFormatter.format(date)
},
locale,
dir: isLocaleRTL(locale.code) ? 'rtl' : 'ltr',
formatters: {
formatWeekdayName: date => {
return weekdayNarrowFormatter.format(date);
},
formatCaption: date => {
return monthNameFormatter.format(date);
}
},
timeZone
};
}, [locale, timeZone, mode]);
};
//# sourceMappingURL=use-localization-props.js.map