@codecademy/gamut
68.2.268.2.3-alpha.f19d29.0
dist/DatePicker/Calendar/utils/format.js+
dist/DatePicker/Calendar/utils/format.jsNew file+72
Index: package/dist/DatePicker/Calendar/utils/format.js
===================================================================
--- package/dist/DatePicker/Calendar/utils/format.js
+++ package/dist/DatePicker/Calendar/utils/format.js
@@ -0,0 +1,72 @@
+import { stringifyLocale } from '../../utils/locale';
+
+/**
+ * Capitalize the first character of a string using the locale; rest unchanged (e.g. "next month" → "Next month").
+ */
+export const capitalizeFirst = (str, locale) => str.length === 0 ? str : str[0].toLocaleUpperCase(stringifyLocale(locale)) + str.slice(1);
+
+/**
+ * Format month and year for the calendar header (e.g. "February 2026").
+ */
+export const formatMonthYear = (date, locale) => {
+ return new Intl.DateTimeFormat(stringifyLocale(locale), {
+ month: 'long',
+ year: 'numeric'
+ }).format(date);
+};
+
+/**
+ * Get weekday names for column headers or abbr attributes.
+ * Column order follows `firstWeekday` (ISO 1 = Monday … 7 = Sunday), matching `Intl.Locale#getWeekInfo().firstDay`.
+ * @param format - 'short' for abbreviated (e.g. "Su", "Mo"), 'long' for full (e.g. "Sunday", "Monday")
+ */
+export const getWeekdayNames = (format, locale, firstWeekday) => {
+ const formatter = new Intl.DateTimeFormat(stringifyLocale(locale), {
+ weekday: format
+ });
+ const monday = new Date(2024, 0, 8);
+ const namesMonToSun = Array.from({
+ length: 7
+ }, (_, i) => {
+ const date = new Date(monday);
+ date.setDate(monday.getDate() + i);
+ return formatter.format(date);
+ });
+ return Array.from({
+ length: 7
+ }, (_, j) => {
+ const iso = (firstWeekday - 1 + j) % 7 + 1;
+ return namesMonToSun[iso - 1];
+ });
+};
+
+/**
+ * Get localized "next month" and "previous month" labels for calendar nav.
+ * Uses Intl.RelativeTimeFormat with numeric: "auto" (e.g. "next month", "last month").
+ */
+export const getRelativeMonthLabels = locale => {
+ const rtf = new Intl.RelativeTimeFormat(stringifyLocale(locale), {
+ numeric: 'auto'
+ });
+ return {
+ nextMonth: capitalizeFirst(rtf.format(1, 'month'), locale),
+ lastMonth: capitalizeFirst(rtf.format(-1, 'month'), locale)
+ };
+};
+
+/**
+ * Get localized "today" label (e.g. "today").
+ */
+export const getRelativeTodayLabel = locale => {
+ const rtf = new Intl.RelativeTimeFormat(stringifyLocale(locale), {
+ numeric: 'auto'
+ });
+ return capitalizeFirst(rtf.format(0, 'day'), locale);
+};
+export const formatDateForAriaLabel = (date, locale) => {
+ return new Intl.DateTimeFormat(stringifyLocale(locale), {
+ month: 'long',
+ day: 'numeric',
+ year: 'numeric'
+ }).format(date);
+};
\ No newline at end of file