-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Expand file tree
/
Copy pathmonth_dropdown_options.tsx
More file actions
90 lines (80 loc) · 2.57 KB
/
month_dropdown_options.tsx
File metadata and controls
90 lines (80 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import React, { Component } from "react";
import { ClickOutsideWrapper } from "./click_outside_wrapper";
interface MonthDropdownOptionsProps {
onCancel: VoidFunction;
onChange: (month: number) => void;
month: number;
monthNames: string[];
}
export default class MonthDropdownOptions extends Component<MonthDropdownOptionsProps> {
monthOptionButtonsRef: Record<number, HTMLDivElement | null> = {};
isSelectedMonth = (i: number): boolean => this.props.month === i;
handleOptionKeyDown = (i: number, e: React.KeyboardEvent): void => {
switch (e.key) {
case "Enter":
e.preventDefault();
this.onChange(i);
break;
case "Escape":
e.preventDefault();
this.props.onCancel();
break;
case "ArrowUp":
case "ArrowDown": {
e.preventDefault();
const newMonth =
(i + (e.key === "ArrowUp" ? -1 : 1) + this.props.monthNames.length) %
this.props.monthNames.length;
this.monthOptionButtonsRef[newMonth]?.focus();
break;
}
}
};
renderOptions = (): React.ReactElement[] => {
// Clear refs to prevent memory leaks on re-render
this.monthOptionButtonsRef = {};
return this.props.monthNames.map<React.ReactElement>(
(month: string, i: number): React.ReactElement => (
<div
ref={(el) => {
this.monthOptionButtonsRef[i] = el;
if (this.isSelectedMonth(i)) {
el?.focus();
}
}}
role="button"
aria-label={`Select Month ${month}`}
tabIndex={0}
className={
this.isSelectedMonth(i)
? "react-datepicker__month-option react-datepicker__month-option--selected_month"
: "react-datepicker__month-option"
}
key={month}
onClick={this.onChange.bind(this, i)}
onKeyDown={this.handleOptionKeyDown.bind(this, i)}
aria-selected={this.isSelectedMonth(i) ? "true" : undefined}
>
{this.isSelectedMonth(i) ? (
<span className="react-datepicker__month-option--selected">✓</span>
) : (
""
)}
{month}
</div>
),
);
};
onChange = (month: number): void => this.props.onChange(month);
handleClickOutside = (): void => this.props.onCancel();
render(): React.ReactElement {
return (
<ClickOutsideWrapper
className="react-datepicker__month-dropdown"
onClickOutside={this.handleClickOutside}
>
{this.renderOptions()}
</ClickOutsideWrapper>
);
}
}