UNPKG

@wordpress/components

Version:
154 lines (151 loc) 4.73 kB
/** * 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