Skip to content
This repository was archived by the owner on Oct 12, 2023. It is now read-only.

Commit 7341e65

Browse files
authored
Merge pull request #26 from misteinb/bugfix/screen-reader-support-for-calendar
add aria label to calendar days
2 parents 11c62ca + 7b28f58 commit 7341e65

File tree

6 files changed

+27
-38
lines changed

6 files changed

+27
-38
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# CHANGELOG
22

3+
## v3.0.3
4+
### Fixed
5+
- screen reader support for calendar
6+
- take in props to override browser locale for calendar
7+
38
## v3.0.2
49
### Fixed
510
- expose callback for clicking calendar icon in date picker. includes next visible state.

lib/components/DateTime/Calendar.tsx

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export interface CalendarAttributes {
2323
export interface CalendarProps extends React.Props<CalendarComponentType> {
2424
/** Current selected date */
2525
value?: Date | string;
26+
/** i18n locale */
27+
locale?: string;
2628

2729
/** Year to display (otherwise shows the year from value) */
2830
year?: number;
@@ -52,8 +54,6 @@ export interface CalendarState {
5254
currentDate: MethodDate;
5355
/** Whether or not props.year/month updates update the view */
5456
detached: boolean;
55-
/** Whether accessibility is activated */
56-
accessibility: boolean;
5757
}
5858

5959
/**
@@ -86,7 +86,6 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
8686

8787

8888
constructor(props: CalendarProps) {
89-
const locale = navigator['userLanguage'] || (navigator.language || 'en-us');
9089
super(props);
9190

9291
if (typeof (this.props.value) === 'string') {
@@ -107,36 +106,19 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
107106
currentDate.date = 1;
108107
this.state = {
109108
currentDate: currentDate,
110-
detached: false,
111-
accessibility: false
109+
detached: false
112110
};
113111

114-
this.monthNames = getLocalMonths(locale);
112+
this.monthNames = getLocalMonths(this.props.locale);
115113

116-
this.dayNames = getLocalWeekdays(locale);
114+
this.dayNames = getLocalWeekdays(this.props.locale);
117115

118116
this.onPrevMonth = this.onPrevMonth.bind(this);
119117
this.onNextMonth = this.onNextMonth.bind(this);
120118
this.onKeyDown = this.onKeyDown.bind(this);
121119
this.setContainerRef = this.setContainerRef.bind(this);
122120
}
123121

124-
public startAccessibility() {
125-
const newDate = this.state.currentDate.copy();
126-
newDate.date = 1;
127-
128-
this.setState({
129-
accessibility: true,
130-
currentDate: newDate
131-
});
132-
}
133-
134-
public stopAccessibility() {
135-
this.setState({
136-
accessibility: false
137-
});
138-
}
139-
140122
componentWillReceiveProps(newProps: CalendarProps) {
141123
const date = this.state.currentDate.copy();
142124
let update = false;
@@ -182,20 +164,11 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
182164
this.props.onChange(date.dateObject);
183165
this.setState({
184166
currentDate: MethodDate.fromDate(this.props.localTimezone, date.dateObject),
185-
detached: false,
186-
accessibility: false
167+
detached: false
187168
});
188169
}
189170
}
190171

191-
onFocus(date: number, event) {
192-
if (!this.state.accessibility) {
193-
const newDate = this.state.currentDate.copy();
194-
newDate.date = date;
195-
this.setState({ currentDate: newDate, accessibility: true });
196-
}
197-
}
198-
199172
onPrevMonth(event) {
200173
event.preventDefault();
201174

@@ -349,16 +322,17 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
349322
event.preventDefault();
350323
};
351324

352-
// TODO aria-label with date
353-
354325
const date = col.date;
355326
const colMonth = col.month;
356327
const key = `${colMonth}-${date}`;
328+
const ariaLabel = new Date(`${curYear}-${colMonth + 1}-${date}`).toLocaleDateString(this.props.locale, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
329+
357330
/** Grayed out day from another month */
358331
if (colMonth !== curMonth) {
359332
return (
360333
<Attr.button
361334
type='button'
335+
aria-label={ariaLabel}
362336
data-row={rowIndex}
363337
data-col={colIndex}
364338
onKeyDown={this.onKeyDown}
@@ -384,13 +358,13 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
384358
return (
385359
<Attr.button
386360
type='button'
361+
aria-label={ariaLabel}
387362
data-row={rowIndex}
388363
data-col={colIndex}
389364
onKeyDown={this.onKeyDown}
390365
className={css('selected')}
391366
onClick={onClick}
392367
key={key}
393-
onFocus={this.onFocus.bind(this, date)}
394368
attr={this.props.attr.dateButton}
395369
>
396370
{date}
@@ -403,12 +377,12 @@ export class Calendar extends React.Component<CalendarProps, Partial<CalendarSta
403377
return (
404378
<Attr.button
405379
type='button'
380+
aria-label={ariaLabel}
406381
data-row={rowIndex}
407382
data-col={colIndex}
408383
onKeyDown={this.onKeyDown}
409384
onClick={onClick}
410385
key={key}
411-
onFocus={this.onFocus.bind(this, date)}
412386
attr={this.props.attr.dateButton}
413387
>
414388
{date}

lib/components/DateTime/DateField.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ export interface DateFieldProps extends React.Props<DateFieldType> {
2424
* Default: true
2525
*/
2626
localTimezone?: boolean;
27+
/** i18n locale */
28+
locale?: string;
2729
/**
2830
* Show Calendar below date picker input
2931
*/
@@ -114,6 +116,7 @@ export const DateField: React.StatelessComponent<DateFieldProps> = (props: DateF
114116
<DatePicker
115117
name={props.name}
116118
initialValue={props.initialValue}
119+
locale={props.locale}
117120
localTimezone={props.localTimezone}
118121
tabIndex={props.tabIndex}
119122
showAbove={props.showAbove}

lib/components/DateTime/DatePicker.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ export interface DatePickerProps extends React.Props<DatePickerType> {
4242
* Default: true
4343
*/
4444
localTimezone?: boolean;
45+
46+
/** i18n locale */
47+
locale?: string;
4548
/**
4649
* Show Calendar below date picker input
4750
*/
@@ -446,6 +449,7 @@ export class DatePicker extends React.Component<DatePickerProps, Partial<DatePic
446449
className={css('date-picker-calendar')}
447450
year={parsed.year || null}
448451
month={parsed.month - 1}
452+
locale={this.props.locale}
449453
attr={this.props.attr.calendar}
450454
/>
451455
<div className={css('date-picker-dropdown-triangle')}></div>

lib/components/DateTime/DateTimeField.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ export interface DateTimeFieldProps extends React.Props<DateTimeFieldType> {
4646
* Default: true
4747
*/
4848
localTimezone?: boolean;
49+
/** i18n locale */
50+
locale?: string;
4951
/**
5052
* Show Calendar below date picker input
5153
*/
@@ -370,6 +372,7 @@ export class DateTimeField extends React.Component<DateTimeFieldProps, Partial<D
370372
tabIndex={this.props.tabIndex}
371373
error={!!this.props.error}
372374
disabled={this.props.disabled}
375+
locale={this.props.locale}
373376
localTimezone={this.props.localTimezone}
374377
showAbove={this.props.showAbove}
375378
format={this.props.format}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@azure-iot/ux-fluent-controls",
3-
"version": "3.0.2",
3+
"version": "3.0.3",
44
"description": "Azure IoT Fluent React Controls",
55
"main": "./lib/index.js",
66
"types": "./lib/index.d.ts",

0 commit comments

Comments
 (0)