Skip to content

Commit

Permalink
resolving selection issue and aria labels for calendar header navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
dpitcock committed Dec 11, 2024
1 parent aee857b commit 24aba24
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 33 deletions.
3 changes: 3 additions & 0 deletions pages/date-range-picker/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ export const i18nStrings: DateRangePickerProps['i18nStrings'] = {
todayAriaLabel: 'Today',
nextMonthAriaLabel: 'Next month',
previousMonthAriaLabel: 'Previous month',
nextYearAriaLabel: 'Next year',
previousYearAriaLabel: 'Previous year',
currentMonthAriaLabel: 'Current month',
customRelativeRangeDurationLabel: 'Duration',
customRelativeRangeDurationPlaceholder: 'Enter duration',
customRelativeRangeOptionLabel: 'Custom range',
Expand Down
4 changes: 2 additions & 2 deletions src/date-range-picker/calendar/grids/grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export function Grid({
const isMonthPicker = granularity === 'month';
const weekdays = weeks[0].map(date => date.getDay());
const normalizedLocale = normalizeLocale('DateRangePicker', locale ?? null);
const quarters = useCalendarGridRows({ baseDate, granularity: 'month', locale: normalizedLocale });
const quarters = useCalendarGridRows({ baseDate, granularity: 'month', locale: normalizedLocale, startOfWeek });
const rows = isMonthPicker ? quarters : weeks;

return (
Expand Down Expand Up @@ -254,7 +254,7 @@ export function Grid({
})}
aria-selected={isEnabled ? isSelected || dateIsInRange : undefined}
aria-current={isCurrent ? 'date' : undefined}
data-date={formatDate(date)}
data-date={formatDate(date, granularity)}
aria-disabled={!isEnabled}
tabIndex={tabIndex}
disabledReason={isDisabledWithReason ? disabledReason : undefined}
Expand Down
1 change: 0 additions & 1 deletion src/date-range-picker/calendar/grids/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ export const Grids = ({
const isRangeVisible = (selectedStartDate && selectedEndDate) || gridHasFocus;

const rangeEnds: Date[] = [selectedStartDate ?? focusedDate, selectedEndDate ?? focusedDate].filter(hasValue);

const rangeStartDate = min(rangeEnds);
const rangeEndDate = max(rangeEnds);
const pageUnit = isMonthPicker ? 'year' : 'month';
Expand Down
19 changes: 11 additions & 8 deletions src/date-range-picker/calendar/header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import React from 'react';
import { add } from 'date-fns';

import { CalendarProps } from '../../../calendar/interfaces';
import { renderMonthAndYear, renderYear } from '../../../calendar/utils/intl';
import { useInternalI18n } from '../../../i18n/context.js';
import InternalLiveRegion from '../../../live-region/internal';
import { Granularity } from '../../interfaces';
import { NextPageButton, PrevPageButton } from './header-button';

import styles from '../../styles.css.js';
Expand All @@ -19,7 +19,7 @@ interface CalendarHeaderProps {
nextPageLabel?: string;
isSingleGrid: boolean;
headingIdPrefix: string;
granularity?: CalendarProps.Granularity;
granularity?: Granularity;
}

export default function CalendarHeader({
Expand All @@ -32,11 +32,14 @@ export default function CalendarHeader({
headingIdPrefix,
granularity = 'day',
}: CalendarHeaderProps) {
const i18n = useInternalI18n('calendar');
const i18n = useInternalI18n('date-range-picker');
const isMonthPicker = granularity === 'month';
const renderLabel = isMonthPicker ? renderYear : renderMonthAndYear;
const prevPageLabel = renderLabel(locale, add(baseDate, granularity === 'month' ? { years: -1 } : { months: -1 }));
const currentPageLabel = renderLabel(locale, baseDate);
const prevPageHeaderLabel = renderLabel(
locale,
add(baseDate, granularity === 'month' ? { years: -1 } : { months: -1 })
);
const currentPageHeaderLabel = renderLabel(locale, baseDate);
const pageUnit = isMonthPicker ? 'year' : 'month';

return (
Expand All @@ -52,11 +55,11 @@ export default function CalendarHeader({
<h2 className={styles['calendar-header-pages-wrapper']}>
{!isSingleGrid && (
<span className={styles['calendar-header-page']} id={`${headingIdPrefix}-prev${pageUnit}`}>
{prevPageLabel}
{prevPageHeaderLabel}
</span>
)}
<span className={styles['calendar-header-page']} id={`${headingIdPrefix}-current${pageUnit}`}>
{currentPageLabel}
{currentPageHeaderLabel}
</span>
</h2>
<NextPageButton
Expand All @@ -65,7 +68,7 @@ export default function CalendarHeader({
/>
</div>
<InternalLiveRegion hidden={true}>
{isSingleGrid ? currentPageLabel : `${prevPageLabel}, ${currentPageLabel}`}
{isSingleGrid ? currentPageHeaderLabel : `${prevPageHeaderLabel}, ${currentPageHeaderLabel}`}
</InternalLiveRegion>
</>
);
Expand Down
33 changes: 18 additions & 15 deletions src/date-range-picker/calendar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,12 @@ export default function DateRangePickerCalendar({

// If both fields are empty, we set the start date
if (!start.date && !end.date) {
newStart = hideTime ? selectedDate : startOfDay(selectedDate);
newStart = startOfDay(selectedDate);
announcement = announceStart(newStart);
}
// If both fields are set, we start new
else if (start.date && end.date) {
newStart = hideTime ? selectedDate : startOfDay(selectedDate);
newStart = startOfDay(selectedDate);
newEnd = null;
announcement = announceStart(newStart);
}
Expand All @@ -164,11 +164,11 @@ export default function DateRangePickerCalendar({

if (isBefore(selectedDate, parsedStartDate)) {
// The user has selected the range backwards, so we swap start and end
newStart = hideTime ? selectedDate : startOfDay(selectedDate);
newEnd = hideTime ? parsedStartDate : endOfDay(parsedStartDate);
newStart = startOfDay(selectedDate);
newEnd = endOfDay(parsedStartDate);
announcement = announceStart(newStart) + announceRange(newStart, newEnd);
} else {
newEnd = hideTime ? selectedDate : endOfDay(selectedDate);
newEnd = endOfDay(selectedDate);
announcement = announceEnd(newEnd) + announceRange(parsedStartDate, newEnd);
}
}
Expand All @@ -178,18 +178,19 @@ export default function DateRangePickerCalendar({

if (isAfter(selectedDate, existingEndDate)) {
// The user has selected the range backwards, so we swap start and end
newStart = hideTime ? existingEndDate : startOfDay(existingEndDate);
newEnd = hideTime ? selectedDate : endOfDay(selectedDate);
newStart = startOfDay(existingEndDate);
newEnd = endOfDay(selectedDate);
announcement = announceEnd(newEnd) + announceRange(newStart, newEnd);
} else {
newStart = hideTime ? selectedDate : startOfDay(selectedDate);
newStart = startOfDay(selectedDate);
announcement = announceStart(newStart) + announceRange(newStart, existingEndDate);
}
}

const formatCurrentValue = (
const formatValue = (
date: Date | null | undefined,
previous: DateRangePickerProps.DateTimeStrings
previous: DateRangePickerProps.DateTimeStrings,
includeTime: boolean
): DateRangePickerProps.DateTimeStrings => {
if (date === null) {
// explicitly reset to empty
Expand All @@ -198,7 +199,7 @@ export default function DateRangePickerCalendar({
// keep old value
return previous;
}
if (hideTime) {
if (!includeTime) {
return {
date: formatDate(date),
time: '',
Expand All @@ -208,8 +209,8 @@ export default function DateRangePickerCalendar({
};

setValue({
start: formatCurrentValue(newStart, value.start),
end: formatCurrentValue(newEnd, value.end),
start: formatValue(newStart, value.start, !hideTime),
end: formatValue(newEnd, value.end, !hideTime),
});
setAnnouncement(announcement);
};
Expand Down Expand Up @@ -240,6 +241,7 @@ export default function DateRangePickerCalendar({
};

const headingIdPrefix = useUniqueId('date-range-picker-calendar-heading');

return (
<>
<div
Expand Down Expand Up @@ -279,8 +281,9 @@ export default function DateRangePickerCalendar({
onPageChange={setCurrentPage}
startOfWeek={normalizedStartOfWeek}
todayAriaLabel={i18nStrings?.todayAriaLabel}
selectedStartDate={parseDate(value.start.date, !isMonthPicker)}
selectedEndDate={parseDate(value.end.date, !isMonthPicker)}
currentMonthAriaLabel={i18nStrings?.currentMonthAriaLabel}
selectedStartDate={value?.start?.date ? parseDate(value.start.date, !isMonthPicker) : null}
selectedEndDate={value?.end?.date ? parseDate(value.end.date, !isMonthPicker) : null}
headingIdPrefix={headingIdPrefix}
/>
</div>
Expand Down
2 changes: 2 additions & 0 deletions src/date-range-picker/calendar/range-inputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export default function RangeInputs({
const dateInputPlaceholder = isMonthPicker ? 'YYYY/MM' : 'YYYY/MM/DD';
const showTimeInput = !dateOnly && !isMonthPicker;

//todo confirm if other dateTimeConstraint texts needed for i18n

return (
<InternalFormField constraintText={i18n('i18nStrings.dateTimeConstraintText', i18nStrings?.dateTimeConstraintText)}>
<div className={styles['date-and-time-container']}>
Expand Down
9 changes: 2 additions & 7 deletions src/date-range-picker/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,11 @@ export function DateRangePickerDropdown({
useEffect(() => {
if (applyClicked) {
const visibleRange =
rangeSelectionMode === 'relative'
? selectedRelativeRange
: joinAbsoluteValue(selectedAbsoluteRange, dateOnly || isMonthPicker);
rangeSelectionMode === 'relative' ? selectedRelativeRange : joinAbsoluteValue(selectedAbsoluteRange);
const formattedRange = formatValue(visibleRange, {
dateOnly,
monthOnly: isMonthPicker,
timeOffset:
dateOnly || isMonthPicker
? { startDate: undefined, endDate: undefined }
: normalizeTimeOffset(visibleRange, getTimeOffset, timeOffset),
timeOffset: dateOnly || isMonthPicker ? null : normalizeTimeOffset(visibleRange, getTimeOffset, timeOffset),
});
const newValidationResult = isValidRange(formattedRange);
setValidationResult(newValidationResult || VALID_RANGE);
Expand Down

0 comments on commit 24aba24

Please sign in to comment.