UNPKG

4.58 kBJavaScriptView Raw
1/*
2 * Copyright 2015 Palantir Technologies, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import * as React from "react";
17import { AbstractPureComponent2, Divider, HTMLSelect, IconSize } from "@blueprintjs/core";
18import * as Classes from "./common/classes";
19import { clone } from "./common/dateUtils";
20import { measureTextWidth } from "./common/utils";
21export class DatePickerCaption extends AbstractPureComponent2 {
22 state = { monthRightOffset: 0 };
23 containerElement;
24 displayedMonthText;
25 handleMonthSelectChange = this.dateChangeHandler((d, month) => d.setMonth(month), this.props.onMonthChange);
26 handleYearSelectChange = this.dateChangeHandler((d, year) => d.setFullYear(year), this.props.onYearChange);
27 render() {
28 const { date, locale, localeUtils, minDate, maxDate, months = localeUtils.getMonths(locale) } = this.props;
29 const minYear = minDate.getFullYear();
30 const maxYear = maxDate.getFullYear();
31 const displayMonth = date.getMonth();
32 const displayYear = date.getFullYear();
33 // build the list of available months, limiting based on minDate and maxDate as necessary
34 const startMonth = displayYear === minYear ? minDate.getMonth() : 0;
35 const endMonth = displayYear === maxYear ? maxDate.getMonth() + 1 : undefined;
36 const monthOptionElements = months
37 .map((month, i) => ({ label: month, value: i }))
38 .slice(startMonth, endMonth);
39 const years = [minYear];
40 for (let year = minYear + 1; year <= maxYear; ++year) {
41 years.push(year);
42 }
43 // allow out-of-bounds years but disable the option. this handles the Dec 2016 case in #391.
44 if (displayYear > maxYear) {
45 years.push({ value: displayYear, disabled: true });
46 }
47 this.displayedMonthText = months[displayMonth];
48 const monthSelect = (React.createElement(HTMLSelect, { "aria-label": "Month", iconProps: { style: { right: this.state.monthRightOffset } }, className: Classes.DATEPICKER_MONTH_SELECT, key: "month", minimal: true, onChange: this.handleMonthSelectChange, value: displayMonth, options: monthOptionElements }));
49 const yearSelect = (React.createElement(HTMLSelect, { "aria-label": "Year", className: Classes.DATEPICKER_YEAR_SELECT, key: "year", minimal: true, onChange: this.handleYearSelectChange, value: displayYear, options: years }));
50 const orderedSelects = this.props.reverseMonthAndYearMenus
51 ? [yearSelect, monthSelect]
52 : [monthSelect, yearSelect];
53 return (React.createElement("div", { className: this.props.classNames.caption },
54 React.createElement("div", { className: Classes.DATEPICKER_CAPTION, ref: ref => (this.containerElement = ref) }, orderedSelects),
55 React.createElement(Divider, null)));
56 }
57 componentDidMount() {
58 this.requestAnimationFrame(() => this.positionArrows());
59 }
60 componentDidUpdate() {
61 this.positionArrows();
62 }
63 positionArrows() {
64 // measure width of text as rendered inside our container element.
65 const monthTextWidth = measureTextWidth(this.displayedMonthText, Classes.DATEPICKER_CAPTION_MEASURE, this.containerElement);
66 const monthSelectWidth = this.containerElement == null ? 0 : this.containerElement.firstElementChild.clientWidth;
67 const rightOffset = Math.max(2, monthSelectWidth - monthTextWidth - IconSize.STANDARD - 2);
68 this.setState({ monthRightOffset: rightOffset });
69 }
70 dateChangeHandler(updater, handler) {
71 return (e) => {
72 const value = parseInt(e.target.value, 10);
73 // ignore change events with invalid values to prevent crash on iOS Safari (#4178)
74 if (isNaN(value)) {
75 return;
76 }
77 const newDate = clone(this.props.date);
78 updater(newDate, value);
79 this.props.onDateChange?.(newDate);
80 handler?.(value);
81 };
82 }
83}
84//# sourceMappingURL=datePickerCaption.js.map
\No newline at end of file