diff options
author | Wouter Admiraal <wouter.admiraal@sonarsource.com> | 2022-10-07 11:55:59 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-10-11 20:03:59 +0000 |
commit | 56884c45a276d804ff0aba9eb7e2c7fc417cf1bb (patch) | |
tree | e5f3e358fab2058c1bf0dea8f704b27da853e30b /server/sonar-web/src/main/js | |
parent | f653953989d9cdefaf48280831163fb169e3208a (diff) | |
download | sonarqube-56884c45a276d804ff0aba9eb7e2c7fc417cf1bb.tar.gz sonarqube-56884c45a276d804ff0aba9eb7e2c7fc417cf1bb.zip |
[NO JIRA] Make date picker dropdown dismissable on Esc
Diffstat (limited to 'server/sonar-web/src/main/js')
-rw-r--r-- | server/sonar-web/src/main/js/components/controls/DateInput.tsx | 129 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap | 638 |
2 files changed, 393 insertions, 374 deletions
diff --git a/server/sonar-web/src/main/js/components/controls/DateInput.tsx b/server/sonar-web/src/main/js/components/controls/DateInput.tsx index 166d7717aee..67168910d28 100644 --- a/server/sonar-web/src/main/js/components/controls/DateInput.tsx +++ b/server/sonar-web/src/main/js/components/controls/DateInput.tsx @@ -35,6 +35,7 @@ import { translate } from '../../helpers/l10n'; import './DayPicker.css'; +import EscKeydownHandler from './EscKeydownHandler'; import Select from './Select'; import './styles.css'; @@ -163,71 +164,73 @@ export default class DateInput extends React.PureComponent<Props, State> { return ( <OutsideClickHandler onClickOutside={this.closeCalendar}> - <span className={classNames('date-input-control', className)}> - <InputWrapper - className={classNames('date-input-control-input', inputClassName, { - 'is-filled': value !== undefined - })} - id={id} - innerRef={(node: HTMLInputElement | null) => (this.input = node)} - name={name} - onFocus={this.openCalendar} - placeholder={placeholder} - readOnly={true} - type="text" - value={value} - /> - <CalendarIcon className="date-input-control-icon" fill="" /> - {value !== undefined && ( - <ClearButton - aria-label={translate('reset_verb')} - className="button-tiny date-input-control-reset" - iconProps={{ size: 12 }} - onClick={this.handleResetClick} + <EscKeydownHandler onKeydown={this.closeCalendar}> + <span className={classNames('date-input-control', className)}> + <InputWrapper + className={classNames('date-input-control-input', inputClassName, { + 'is-filled': value !== undefined + })} + id={id} + innerRef={(node: HTMLInputElement | null) => (this.input = node)} + name={name} + onFocus={this.openCalendar} + placeholder={placeholder} + readOnly={true} + type="text" + value={value} /> - )} - {open && ( - <div className="date-input-calendar"> - <nav className="date-input-calendar-nav"> - <ButtonIcon className="button-small" onClick={this.handlePreviousMonthClick}> - <ChevronLeftIcon /> - </ButtonIcon> - <div className="date-input-calender-month"> - <Select - aria-label={translate('select_month')} - className="date-input-calender-month-select" - onChange={this.handleCurrentMonthChange} - options={monthOptions} - value={monthOptions.find(month => month.value === currentMonth.getMonth())} - /> - <Select - aria-label={translate('select_year')} - className="date-input-calender-month-select spacer-left" - onChange={this.handleCurrentYearChange} - options={yearOptions} - value={yearOptions.find(year => year.value === currentMonth.getFullYear())} - /> - </div> - <ButtonIcon className="button-small" onClick={this.handleNextMonthClick}> - <ChevronRightIcon /> - </ButtonIcon> - </nav> - <DayPicker - captionElement={<NullComponent />} - disabledDays={{ after, before: minDate }} - firstDayOfWeek={1} - modifiers={modifiers} - month={currentMonth} - navbarElement={<NullComponent />} - onDayClick={this.handleDayClick} - onDayMouseEnter={this.handleDayMouseEnter} - selectedDays={selectedDays} - weekdaysLong={weekdaysLong} - weekdaysShort={weekdaysShort} + <CalendarIcon className="date-input-control-icon" fill="" /> + {value !== undefined && ( + <ClearButton + aria-label={translate('reset_verb')} + className="button-tiny date-input-control-reset" + iconProps={{ size: 12 }} + onClick={this.handleResetClick} /> - </div> - )} - </span> + )} + {open && ( + <div className="date-input-calendar"> + <nav className="date-input-calendar-nav"> + <ButtonIcon className="button-small" onClick={this.handlePreviousMonthClick}> + <ChevronLeftIcon /> + </ButtonIcon> + <div className="date-input-calender-month"> + <Select + aria-label={translate('select_month')} + className="date-input-calender-month-select" + onChange={this.handleCurrentMonthChange} + options={monthOptions} + value={monthOptions.find(month => month.value === currentMonth.getMonth())} + /> + <Select + aria-label={translate('select_year')} + className="date-input-calender-month-select spacer-left" + onChange={this.handleCurrentYearChange} + options={yearOptions} + value={yearOptions.find(year => year.value === currentMonth.getFullYear())} + /> + </div> + <ButtonIcon className="button-small" onClick={this.handleNextMonthClick}> + <ChevronRightIcon /> + </ButtonIcon> + </nav> + <DayPicker + captionElement={<NullComponent />} + disabledDays={{ after, before: minDate }} + firstDayOfWeek={1} + modifiers={modifiers} + month={currentMonth} + navbarElement={<NullComponent />} + onDayClick={this.handleDayClick} + onDayMouseEnter={this.handleDayMouseEnter} + selectedDays={selectedDays} + weekdaysLong={weekdaysLong} + weekdaysShort={weekdaysShort} + /> + </div> + )} + </span> + </EscKeydownHandler> </OutsideClickHandler> ); } diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap index fab0f857c18..6a3e0e6fb19 100644 --- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap @@ -4,22 +4,26 @@ exports[`should render 1`] = ` <OutsideClickHandler onClickOutside={[Function]} > - <span - className="date-input-control" + <EscKeydownHandler + onKeydown={[Function]} > - <injectIntl(Component) - className="date-input-control-input" - innerRef={[Function]} - onFocus={[Function]} - placeholder="placeholder" - readOnly={true} - type="text" - /> - <CalendarIcon - className="date-input-control-icon" - fill="" - /> - </span> + <span + className="date-input-control" + > + <injectIntl(Component) + className="date-input-control-input" + innerRef={[Function]} + onFocus={[Function]} + placeholder="placeholder" + readOnly={true} + type="text" + /> + <CalendarIcon + className="date-input-control-icon" + fill="" + /> + </span> + </EscKeydownHandler> </OutsideClickHandler> `; @@ -27,33 +31,37 @@ exports[`should render 2`] = ` <OutsideClickHandler onClickOutside={[Function]} > - <span - className="date-input-control" + <EscKeydownHandler + onKeydown={[Function]} > - <injectIntl(Component) - className="date-input-control-input is-filled" - innerRef={[Function]} - onFocus={[Function]} - placeholder="placeholder" - readOnly={true} - type="text" - value={2018-01-17T00:00:00.000Z} - /> - <CalendarIcon - className="date-input-control-icon" - fill="" - /> - <ClearButton - aria-label="reset_verb" - className="button-tiny date-input-control-reset" - iconProps={ - Object { - "size": 12, + <span + className="date-input-control" + > + <injectIntl(Component) + className="date-input-control-input is-filled" + innerRef={[Function]} + onFocus={[Function]} + placeholder="placeholder" + readOnly={true} + type="text" + value={2018-01-17T00:00:00.000Z} + /> + <CalendarIcon + className="date-input-control-icon" + fill="" + /> + <ClearButton + aria-label="reset_verb" + className="button-tiny date-input-control-reset" + iconProps={ + Object { + "size": 12, + } } - } - onClick={[Function]} - /> - </span> + onClick={[Function]} + /> + </span> + </EscKeydownHandler> </OutsideClickHandler> `; @@ -61,285 +69,289 @@ exports[`should render 3`] = ` <OutsideClickHandler onClickOutside={[Function]} > - <span - className="date-input-control" + <EscKeydownHandler + onKeydown={[Function]} > - <injectIntl(Component) - className="date-input-control-input is-filled" - innerRef={[Function]} - onFocus={[Function]} - placeholder="placeholder" - readOnly={true} - type="text" - value={2018-01-17T00:00:00.000Z} - /> - <CalendarIcon - className="date-input-control-icon" - fill="" - /> - <ClearButton - aria-label="reset_verb" - className="button-tiny date-input-control-reset" - iconProps={ - Object { - "size": 12, - } - } - onClick={[Function]} - /> - <div - className="date-input-calendar" + <span + className="date-input-control" > - <nav - className="date-input-calendar-nav" + <injectIntl(Component) + className="date-input-control-input is-filled" + innerRef={[Function]} + onFocus={[Function]} + placeholder="placeholder" + readOnly={true} + type="text" + value={2018-01-17T00:00:00.000Z} + /> + <CalendarIcon + className="date-input-control-icon" + fill="" + /> + <ClearButton + aria-label="reset_verb" + className="button-tiny date-input-control-reset" + iconProps={ + Object { + "size": 12, + } + } + onClick={[Function]} + /> + <div + className="date-input-calendar" > - <ButtonIcon - className="button-small" - onClick={[Function]} - > - <ChevronLeftIcon /> - </ButtonIcon> - <div - className="date-input-calender-month" + <nav + className="date-input-calendar-nav" > - <Select - aria-label="select_month" - className="date-input-calender-month-select" - onChange={[Function]} - options={ - Array [ + <ButtonIcon + className="button-small" + onClick={[Function]} + > + <ChevronLeftIcon /> + </ButtonIcon> + <div + className="date-input-calender-month" + > + <Select + aria-label="select_month" + className="date-input-calender-month-select" + onChange={[Function]} + options={ + Array [ + Object { + "label": "Jan", + "value": 0, + }, + Object { + "label": "Feb", + "value": 1, + }, + Object { + "label": "Mar", + "value": 2, + }, + Object { + "label": "Apr", + "value": 3, + }, + Object { + "label": "May", + "value": 4, + }, + Object { + "label": "Jun", + "value": 5, + }, + Object { + "label": "Jul", + "value": 6, + }, + Object { + "label": "Aug", + "value": 7, + }, + Object { + "label": "Sep", + "value": 8, + }, + Object { + "label": "Oct", + "value": 9, + }, + Object { + "label": "Nov", + "value": 10, + }, + Object { + "label": "Dec", + "value": 11, + }, + ] + } + value={ Object { "label": "Jan", "value": 0, - }, - Object { - "label": "Feb", - "value": 1, - }, - Object { - "label": "Mar", - "value": 2, - }, - Object { - "label": "Apr", - "value": 3, - }, - Object { - "label": "May", - "value": 4, - }, - Object { - "label": "Jun", - "value": 5, - }, - Object { - "label": "Jul", - "value": 6, - }, - Object { - "label": "Aug", - "value": 7, - }, - Object { - "label": "Sep", - "value": 8, - }, - Object { - "label": "Oct", - "value": 9, - }, - Object { - "label": "Nov", - "value": 10, - }, - Object { - "label": "Dec", - "value": 11, - }, - ] - } - value={ - Object { - "label": "Jan", - "value": 0, + } } - } - /> - <Select - aria-label="select_year" - className="date-input-calender-month-select spacer-left" - onChange={[Function]} - options={ - Array [ - Object { - "label": "2008", - "value": 2008, - }, - Object { - "label": "2009", - "value": 2009, - }, - Object { - "label": "2010", - "value": 2010, - }, - Object { - "label": "2011", - "value": 2011, - }, - Object { - "label": "2012", - "value": 2012, - }, - Object { - "label": "2013", - "value": 2013, - }, - Object { - "label": "2014", - "value": 2014, - }, - Object { - "label": "2015", - "value": 2015, - }, - Object { - "label": "2016", - "value": 2016, - }, - Object { - "label": "2017", - "value": 2017, - }, + /> + <Select + aria-label="select_year" + className="date-input-calender-month-select spacer-left" + onChange={[Function]} + options={ + Array [ + Object { + "label": "2008", + "value": 2008, + }, + Object { + "label": "2009", + "value": 2009, + }, + Object { + "label": "2010", + "value": 2010, + }, + Object { + "label": "2011", + "value": 2011, + }, + Object { + "label": "2012", + "value": 2012, + }, + Object { + "label": "2013", + "value": 2013, + }, + Object { + "label": "2014", + "value": 2014, + }, + Object { + "label": "2015", + "value": 2015, + }, + Object { + "label": "2016", + "value": 2016, + }, + Object { + "label": "2017", + "value": 2017, + }, + Object { + "label": "2018", + "value": 2018, + }, + ] + } + value={ Object { "label": "2018", "value": 2018, - }, - ] - } - value={ - Object { - "label": "2018", - "value": 2018, + } } + /> + </div> + <ButtonIcon + className="button-small" + onClick={[Function]} + > + <ChevronRightIcon /> + </ButtonIcon> + </nav> + <DayPicker + canChangeMonth={true} + captionElement={<NullComponent />} + classNames={ + Object { + "body": "DayPicker-Body", + "caption": "DayPicker-Caption", + "container": "DayPicker", + "day": "DayPicker-Day", + "disabled": "disabled", + "footer": "DayPicker-Footer", + "interactionDisabled": "DayPicker--interactionDisabled", + "month": "DayPicker-Month", + "months": "DayPicker-Months", + "navBar": "DayPicker-NavBar", + "navButtonInteractionDisabled": "DayPicker-NavButton--interactionDisabled", + "navButtonNext": "DayPicker-NavButton DayPicker-NavButton--next", + "navButtonPrev": "DayPicker-NavButton DayPicker-NavButton--prev", + "outside": "outside", + "selected": "selected", + "today": "today", + "todayButton": "DayPicker-TodayButton", + "week": "DayPicker-Week", + "weekNumber": "DayPicker-WeekNumber", + "weekday": "DayPicker-Weekday", + "weekdays": "DayPicker-Weekdays", + "weekdaysRow": "DayPicker-WeekdaysRow", + "wrapper": "DayPicker-wrapper", } - /> - </div> - <ButtonIcon - className="button-small" - onClick={[Function]} - > - <ChevronRightIcon /> - </ButtonIcon> - </nav> - <DayPicker - canChangeMonth={true} - captionElement={<NullComponent />} - classNames={ - Object { - "body": "DayPicker-Body", - "caption": "DayPicker-Caption", - "container": "DayPicker", - "day": "DayPicker-Day", - "disabled": "disabled", - "footer": "DayPicker-Footer", - "interactionDisabled": "DayPicker--interactionDisabled", - "month": "DayPicker-Month", - "months": "DayPicker-Months", - "navBar": "DayPicker-NavBar", - "navButtonInteractionDisabled": "DayPicker-NavButton--interactionDisabled", - "navButtonNext": "DayPicker-NavButton DayPicker-NavButton--next", - "navButtonPrev": "DayPicker-NavButton DayPicker-NavButton--prev", - "outside": "outside", - "selected": "selected", - "today": "today", - "todayButton": "DayPicker-TodayButton", - "week": "DayPicker-Week", - "weekNumber": "DayPicker-WeekNumber", - "weekday": "DayPicker-Weekday", - "weekdays": "DayPicker-Weekdays", - "weekdaysRow": "DayPicker-WeekdaysRow", - "wrapper": "DayPicker-wrapper", } - } - disabledDays={ - Object { - "after": 2018-02-05T00:00:00.000Z, - "before": 2018-01-17T00:00:00.000Z, + disabledDays={ + Object { + "after": 2018-02-05T00:00:00.000Z, + "before": 2018-01-17T00:00:00.000Z, + } } - } - enableOutsideDaysClick={true} - firstDayOfWeek={1} - fixedWeeks={false} - labels={ - Object { - "nextMonth": "Next Month", - "previousMonth": "Previous Month", + enableOutsideDaysClick={true} + firstDayOfWeek={1} + fixedWeeks={false} + labels={ + Object { + "nextMonth": "Next Month", + "previousMonth": "Previous Month", + } } - } - locale="en" - localeUtils={ - Object { - "default": Object { + locale="en" + localeUtils={ + Object { + "default": Object { + "formatDay": [Function], + "formatMonthTitle": [Function], + "formatWeekdayLong": [Function], + "formatWeekdayShort": [Function], + "getFirstDayOfWeek": [Function], + "getMonths": [Function], + }, "formatDay": [Function], "formatMonthTitle": [Function], "formatWeekdayLong": [Function], "formatWeekdayShort": [Function], "getFirstDayOfWeek": [Function], "getMonths": [Function], - }, - "formatDay": [Function], - "formatMonthTitle": [Function], - "formatWeekdayLong": [Function], - "formatWeekdayShort": [Function], - "getFirstDayOfWeek": [Function], - "getMonths": [Function], + } } - } - month={2018-01-17T00:00:00.000Z} - navbarElement={<NullComponent />} - numberOfMonths={1} - onDayClick={[Function]} - onDayMouseEnter={[Function]} - pagedNavigation={false} - renderDay={[Function]} - renderWeek={[Function]} - reverseMonths={false} - selectedDays={ - Array [ - 2018-01-17T00:00:00.000Z, - ] - } - showOutsideDays={false} - showWeekDays={true} - showWeekNumbers={false} - tabIndex={0} - weekdayElement={<Weekday />} - weekdaysLong={ - Array [ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", - ] - } - weekdaysShort={ - Array [ - "Sun", - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat", - ] - } - /> - </div> - </span> + month={2018-01-17T00:00:00.000Z} + navbarElement={<NullComponent />} + numberOfMonths={1} + onDayClick={[Function]} + onDayMouseEnter={[Function]} + pagedNavigation={false} + renderDay={[Function]} + renderWeek={[Function]} + reverseMonths={false} + selectedDays={ + Array [ + 2018-01-17T00:00:00.000Z, + ] + } + showOutsideDays={false} + showWeekDays={true} + showWeekNumbers={false} + tabIndex={0} + weekdayElement={<Weekday />} + weekdaysLong={ + Array [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + ] + } + weekdaysShort={ + Array [ + "Sun", + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat", + ] + } + /> + </div> + </span> + </EscKeydownHandler> </OutsideClickHandler> `; @@ -347,21 +359,25 @@ exports[`should select a day 1`] = ` <OutsideClickHandler onClickOutside={[Function]} > - <span - className="date-input-control" + <EscKeydownHandler + onKeydown={[Function]} > - <injectIntl(Component) - className="date-input-control-input" - innerRef={[Function]} - onFocus={[Function]} - placeholder="placeholder" - readOnly={true} - type="text" - /> - <CalendarIcon - className="date-input-control-icon" - fill="" - /> - </span> + <span + className="date-input-control" + > + <injectIntl(Component) + className="date-input-control-input" + innerRef={[Function]} + onFocus={[Function]} + placeholder="placeholder" + readOnly={true} + type="text" + /> + <CalendarIcon + className="date-input-control-icon" + fill="" + /> + </span> + </EscKeydownHandler> </OutsideClickHandler> `; |