Repository: adobe/react-spectrum
File: packages/@react-spectrum/s2/src/Calendar.tsx (TypeScript)

Code before:
      <CalendarGridHeader>
        {(day) => (
          <CalendarHeaderCell>
            {day}
          </CalendarHeaderCell>
        )}
      </CalendarGridHeader>
      <CalendarGridBody>
        {(date) => (
          <CalendarCell date={date} firstDayOfWeek={props.firstDayOfWeek} />
        )}
      </CalendarGridBody>
    </AriaCalendarGrid>
  );
};

// Ordinarily the heading is a formatted date range, ie January 2025 - February 2025.
// However, we want to show each month individually.
export const CalendarHeading = (): ReactElement => {
  let calendarStateContext = useContext(CalendarStateContext);
  let rangeCalendarStateContext = useContext(RangeCalendarStateContext);
  let {visibleRange, timeZone} = calendarStateContext ?? rangeCalendarStateContext ?? {};
  let monthFormatter = useDateFormatter({
    month: 'long',
    year: 'numeric',
    era: (visibleRange?.start.era ?? visibleRange?.end.era) as 'long' | 'short' | 'narrow' | undefined,
    calendar: visibleRange?.start.calendar.identifier,
    timeZone
  });
  let months = useMemo(() => {
    if (!visibleRange) {
      return [];
    }
    let months: string[] = [];
    for (let i = visibleRange.start; i.compare(visibleRange.end) <= 0; i = i.add({months: 1})) {
      // TODO: account for the first week possibly overlapping, like with a custom 454 calendar.
      // there has to be a better way to do this...
      if (i.month === visibleRange.start.month) {
        i = i.add({weeks: 1});
      }
      months.push(monthFormatter.format(i.toDate(timeZone!)));
    }
    return months;
  }, [visibleRange, monthFormatter, timeZone]);

  return (
    <Heading styles={headingStyles}>
      {months.map((month, i) => {
        if (i === 0) {
          return (
            <Fragment key={month}>

Review comment (suggestion):
should this match v3's `era: currentMonth.calendar.identifier === 'gregory' && currentMonth.era === 'BC' ? 'short' : undefined,`? Right now it looks like it is erroring in s2 storybook

Code after:
      <CalendarGridHeader>
        {(day) => (
          <CalendarHeaderCell>
            {day}
          </CalendarHeaderCell>
        )}
      </CalendarGridHeader>
      <CalendarGridBody>
        {(date) => (
          <CalendarCell date={date} firstDayOfWeek={props.firstDayOfWeek} />
        )}
      </CalendarGridBody>
    </AriaCalendarGrid>
  );
};

// Ordinarily the heading is a formatted date range, ie January 2025 - February 2025.
// However, we want to show each month individually.
export const CalendarHeading = (): ReactElement => {
  let calendarStateContext = useContext(CalendarStateContext);
  let rangeCalendarStateContext = useContext(RangeCalendarStateContext);
  let {visibleRange, timeZone} = calendarStateContext ?? rangeCalendarStateContext ?? {};
  let currentMonth = visibleRange?.start ?? visibleRange?.end;
  let monthFormatter = useDateFormatter({
    month: 'long',
    year: 'numeric',
    era: currentMonth && currentMonth.calendar.identifier === 'gregory' && currentMonth.era === 'BC' ? 'short' : undefined,
    calendar: visibleRange?.start.calendar.identifier,
    timeZone
  });
  let months = useMemo(() => {
    if (!visibleRange) {
      return [];
    }
    let months: string[] = [];
    for (let i = visibleRange.start; i.compare(visibleRange.end) <= 0; i = i.add({months: 1})) {
      // TODO: account for the first week possibly overlapping, like with a custom 454 calendar.
      // there has to be a better way to do this...
      if (i.month === visibleRange.start.month) {
        i = i.add({weeks: 1});
      }
      months.push(monthFormatter.format(i.toDate(timeZone!)));
    }
    return months;
  }, [visibleRange, monthFormatter, timeZone]);

  return (
    <Heading styles={headingStyles}>
      {months.map((month, i) => {
        if (i === 0) {
          return (