Bug 1361676 - Show selection highlight on date picker. r=mconley
MozReview-Commit-ID: GBE5zwWxQiu
--- a/toolkit/content/widgets/calendar.js
+++ b/toolkit/content/widgets/calendar.js
@@ -146,19 +146,17 @@ Calendar.prototype = {
*/
handleEvent(event) {
switch (event.type) {
case "click": {
if (event.target.parentNode == this.context.daysView) {
let targetId = event.target.dataset.id;
let targetObj = this.props.days[targetId];
if (targetObj.enabled) {
- this.props.setSelection({
- selection: targetObj.dateObj
- });
+ this.props.setSelection(targetObj.dateObj);
}
}
break;
}
}
},
/**
--- a/toolkit/content/widgets/datekeeper.js
+++ b/toolkit/content/widgets/datekeeper.js
@@ -29,16 +29,20 @@ function DateKeeper(props) {
get month() {
return this.state.dateObj.getUTCMonth();
},
get day() {
return this.state.dateObj.getUTCDate();
},
+ get selection() {
+ return this.state.selection;
+ },
+
/**
* Initialize DateKeeper
* @param {Number} year
* @param {Number} month
* @param {Number} day
* @param {String} min
* @param {String} max
* @param {Number} firstDayOfWeek
@@ -53,16 +57,17 @@ function DateKeeper(props) {
firstDayOfWeek, weekends, calViewSize,
min: new Date(min != undefined ? min : MIN_DATE),
max: new Date(max != undefined ? max : MAX_DATE),
today: this._newUTCDate(today.getFullYear(), today.getMonth(), today.getDate()),
weekHeaders: this._getWeekHeaders(firstDayOfWeek, weekends),
years: [],
months: [],
days: [],
+ selection: { year, month, day },
};
this.state.dateObj = isDateSet ?
this._newUTCDate(year, month, day) :
new Date(this.state.today);
},
/**
* Set new date. The year is always treated as full year, so the short-form
@@ -76,22 +81,24 @@ function DateKeeper(props) {
*/
set({ year = this.year, month = this.month, day = this.day }) {
// Use setUTCFullYear so that year 99 doesn't get parsed as 1999
this.state.dateObj.setUTCFullYear(year, month, day);
},
/**
* Set selection date
- * @param {Date} selection
+ * @param {Number} year
+ * @param {Number} month
+ * @param {Number} day
*/
- setSelection(selection) {
- this.set({ year: selection.getUTCFullYear(),
- month: selection.getUTCMonth(),
- day: selection.getUTCDate() });
+ setSelection({ year, month, day }) {
+ this.state.selection.year = year;
+ this.state.selection.month = month;
+ this.state.selection.day = day;
},
/**
* Set month. Makes sure the day is <= the last day of the month
* @param {Number} month
*/
setMonth(month) {
const lastDayOfMonth = this._newUTCDate(this.year, month + 1, 0).getUTCDate();
@@ -195,16 +202,21 @@ function DateKeeper(props) {
let classNames = [];
let enabled = true;
if (this.state.weekends.includes(dateObj.getUTCDay())) {
classNames.push("weekend");
}
if (month != dateObj.getUTCMonth()) {
classNames.push("outside");
}
+ if (this.state.selection.year == dateObj.getUTCFullYear() &&
+ this.state.selection.month == dateObj.getUTCMonth() &&
+ this.state.selection.day == dateObj.getUTCDate()) {
+ classNames.push("selection");
+ }
if (dateObj.getTime() < this.state.min.getTime() || dateObj.getTime() > this.state.max.getTime()) {
classNames.push("out-of-range");
enabled = false;
}
if (this.state.today.getTime() == dateObj.getTime()) {
classNames.push("today");
}
days.push({
--- a/toolkit/content/widgets/datepicker.js
+++ b/toolkit/content/widgets/datepicker.js
@@ -52,42 +52,48 @@ function DatePicker(context) {
});
document.dir = dir;
this.state = {
dateKeeper,
locale,
isMonthPickerVisible: false,
- isYearSet: false,
- isMonthSet: false,
- isDateSet: false,
datetimeOrders: new Intl.DateTimeFormat(locale)
.formatToParts(new Date(0)).map(part => part.type),
getDayString: new Intl.NumberFormat(locale).format,
getWeekHeaderString: weekday => weekdayStrings[weekday],
getMonthString: month => monthStrings[month],
- setSelection: ({ selection }) => {
- dateKeeper.setSelection(selection);
- this.state.isYearSet = true;
- this.state.isMonthSet = true;
- this.state.isDateSet = true;
+ setSelection: date => {
+ dateKeeper.setSelection({
+ year: date.getUTCFullYear(),
+ month: date.getUTCMonth(),
+ day: date.getUTCDate(),
+ });
this._update();
this._dispatchState();
this._closePopup();
},
setYear: year => {
dateKeeper.setYear(year);
- this.state.isYearSet = true;
+ dateKeeper.setSelection({
+ year,
+ month: dateKeeper.selection.month,
+ day: dateKeeper.selection.day,
+ });
this._update();
this._dispatchState();
},
setMonth: month => {
dateKeeper.setMonth(month);
- this.state.isMonthSet = true;
+ dateKeeper.setSelection({
+ year: dateKeeper.selection.year,
+ month,
+ day: dateKeeper.selection.day,
+ });
this._update();
this._dispatchState();
},
toggleMonthPicker: () => {
this.state.isMonthPickerVisible = !this.state.isMonthPickerVisible;
this._update();
}
};
@@ -160,29 +166,25 @@ function DatePicker(context) {
name: "ClosePopup"
}, "*");
},
/**
* Use postMessage to pass the state of picker to the panel.
*/
_dispatchState() {
- const { year, month, day } = this.state.dateKeeper;
- const { isYearSet, isMonthSet, isDaySet } = this.state;
+ const { year, month, day } = this.state.dateKeeper.selection;
// The panel is listening to window for postMessage event, so we
// do postMessage to itself to send data to input boxes.
window.postMessage({
name: "PickerPopupChanged",
detail: {
year,
month,
day,
- isYearSet,
- isMonthSet,
- isDaySet
}
}, "*");
},
/**
* Attach event listeners
*/
_attachEventListeners() {
@@ -253,29 +255,22 @@ function DatePicker(context) {
* {Number} year [optional]
* {Number} month [optional]
* {Number} date [optional]
* }
*/
set({ year, month, day }) {
const { dateKeeper } = this.state;
- if (year != undefined) {
- this.state.isYearSet = true;
- }
- if (month != undefined) {
- this.state.isMonthSet = true;
- }
- if (day != undefined) {
- this.state.isDaySet = true;
- }
-
dateKeeper.set({
year, month, day
});
+ dateKeeper.setSelection({
+ year, month, day
+ });
this._update();
}
};
/**
* MonthYear is a component that handles the month & year spinners
*
* @param {Object} options
--- a/toolkit/themes/shared/datetimeinputpickers.css
+++ b/toolkit/themes/shared/datetimeinputpickers.css
@@ -327,43 +327,44 @@ button.month-year.active::after {
text-align: center;
padding: calc((var(--spinner-item-height) - var(--font-size-default)) / 2) 0;
margin-bottom: var(--spinner-item-margin-bottom);
height: var(--spinner-item-height);
-moz-user-select: none;
scroll-snap-coordinate: 0 0;
}
+.spinner-container > .spinner > div::before,
+.calendar-container .days-view > div::before {
+ position: absolute;
+ top: 5%;
+ bottom: 5%;
+ left: 5%;
+ right: 5%;
+ z-index: -10;
+ border-radius: var(--border-radius);
+}
+
.spinner-container > .spinner > div:hover::before,
.calendar-container .days-view > div:hover::before {
background: var(--fill-color);
border: var(--border);
- border-radius: var(--border-radius);
content: "";
- position: absolute;
- z-index: -10;
}
.spinner-container > .spinner:not(.scrolling) > div.selection,
-.calendar-container .days-view > div.selection {
+.calendar-container .days-view > div.selection:not(.out-of-range) {
color: var(--selected-font-color);
}
.spinner-container > .spinner > div.selection::before,
.calendar-container .days-view > div.selection::before {
background: var(--selected-fill-color);
border: none;
- border-radius: var(--border-radius);
content: "";
- position: absolute;
- top: 0%;
- bottom: 0%;
- left: 0%;
- right: 0%;
- z-index: -10;
}
.spinner-container > .spinner > div.disabled::before,
.spinner-container > .spinner.scrolling > div.selection::before,
.spinner-container > .spinner.scrolling > div:hover::before {
display: none;
}