Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
resolving selection issue and aria labels for calendar header navigation
Browse files Browse the repository at this point in the history
dpitcock committed Dec 11, 2024

Verified

This commit was signed with the committer’s verified signature.
Kikobeats Kiko Beats
1 parent 73641df commit d63e7be
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
@@ -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',
4 changes: 2 additions & 2 deletions src/date-range-picker/calendar/grids/grid.tsx
Original file line number Diff line number Diff line change
@@ -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 (
@@ -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}
1 change: 0 additions & 1 deletion src/date-range-picker/calendar/grids/index.tsx
Original file line number Diff line number Diff line change
@@ -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';
19 changes: 11 additions & 8 deletions src/date-range-picker/calendar/header/index.tsx
Original file line number Diff line number Diff line change
@@ -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';
@@ -19,7 +19,7 @@ interface CalendarHeaderProps {
nextPageLabel?: string;
isSingleGrid: boolean;
headingIdPrefix: string;
granularity?: CalendarProps.Granularity;
granularity?: Granularity;
}

export default function CalendarHeader({
@@ -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 (
@@ -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
@@ -65,7 +68,7 @@ export default function CalendarHeader({
/>
</div>
<InternalLiveRegion hidden={true}>
{isSingleGrid ? currentPageLabel : `${prevPageLabel}, ${currentPageLabel}`}
{isSingleGrid ? currentPageHeaderLabel : `${prevPageHeaderLabel}, ${currentPageHeaderLabel}`}
</InternalLiveRegion>
</>
);
33 changes: 18 additions & 15 deletions src/date-range-picker/calendar/index.tsx
Original file line number Diff line number Diff line change
@@ -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);
}
@@ -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);
}
}
@@ -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
@@ -198,7 +199,7 @@ export default function DateRangePickerCalendar({
// keep old value
return previous;
}
if (hideTime) {
if (!includeTime) {
return {
date: formatDate(date),
time: '',
@@ -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);
};
@@ -240,6 +241,7 @@ export default function DateRangePickerCalendar({
};

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

return (
<>
<div
@@ -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>
2 changes: 2 additions & 0 deletions src/date-range-picker/calendar/range-inputs.tsx
Original file line number Diff line number Diff line change
@@ -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']}>
9 changes: 2 additions & 7 deletions src/date-range-picker/dropdown.tsx
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit d63e7be

Please sign in to comment.