Bug 1397114 - Disable smooth scrolling when value changes come from input box
MozReview-Commit-ID: 9ZLSB2HQvcu
--- a/toolkit/content/widgets/datepicker.js
+++ b/toolkit/content/widgets/datepicker.js
@@ -128,32 +128,33 @@ function DatePicker(context) {
monthYearView: this.context.monthYearView
})
};
},
/**
* Update date picker and its components.
*/
- _update() {
+ _update(options = {}) {
const { dateKeeper, isMonthPickerVisible } = this.state;
if (isMonthPickerVisible) {
this.state.months = dateKeeper.getMonths();
this.state.years = dateKeeper.getYears();
} else {
this.state.days = dateKeeper.getDays();
}
this.components.monthYear.setProps({
isVisible: isMonthPickerVisible,
dateObj: dateKeeper.state.dateObj,
months: this.state.months,
years: this.state.years,
- toggleMonthPicker: this.state.toggleMonthPicker
+ toggleMonthPicker: this.state.toggleMonthPicker,
+ noSmoothScroll: options.noSmoothScroll
});
this.components.calendar.setProps({
isVisible: !isMonthPickerVisible,
days: this.state.days,
weekHeaders: dateKeeper.state.weekHeaders
});
isMonthPickerVisible ?
@@ -264,17 +265,17 @@ function DatePicker(context) {
const { dateKeeper } = this.state;
dateKeeper.setCalendarMonth({
year, month
});
dateKeeper.setSelection({
year, month, day
});
- this._update();
+ this._update({ noSmoothScroll: true });
}
};
/**
* MonthYear is a component that handles the month & year spinners
*
* @param {Object} options
* {
@@ -345,24 +346,24 @@ function DatePicker(context) {
if (props.isVisible) {
this.context.monthYear.classList.add("active");
this.components.month.setState({
value: props.dateObj.getUTCMonth(),
items: props.months,
isInfiniteScroll: true,
isValueSet: this.state.isMonthSet,
- smoothScroll: !this.state.firstOpened
+ smoothScroll: !(this.state.firstOpened || props.noSmoothScroll)
});
this.components.year.setState({
value: props.dateObj.getUTCFullYear(),
items: props.years,
isInfiniteScroll: false,
isValueSet: this.state.isYearSet,
- smoothScroll: !this.state.firstOpened
+ smoothScroll: !(this.state.firstOpened || props.noSmoothScroll)
});
this.state.firstOpened = false;
} else {
this.context.monthYear.classList.remove("active");
this.state.isMonthSet = false;
this.state.isYearSet = false;
this.state.firstOpened = true;
}
--- a/toolkit/content/widgets/spinner.js
+++ b/toolkit/content/widgets/spinner.js
@@ -119,38 +119,30 @@ function Spinner(props, context) {
} else {
this._removeSelection();
}
},
/**
* Whenever scroll event is detected:
* - Update the index state
- * - If a smooth scroll has reached its destination, set [isScrolling] state
- * to false
* - If the value has changed, update the [value] state and call [setValue]
* - If infinite scrolling is on, reset the scrolling position if necessary
*/
_onScroll() {
const { items, itemsView, isInfiniteScroll } = this.state;
const { viewportSize, viewportTopOffset } = this.props;
const { spinner } = this.elements;
this.state.index = this._getIndexByOffset(spinner.scrollTop);
const value = itemsView[this.state.index + viewportTopOffset].value;
- // Check if smooth scrolling has reached its destination.
- // This prevents input box jump when input box changes values.
- if (this.state.value == value && this.state.isScrolling) {
- this.state.isScrolling = false;
- }
-
- // Call setValue if value has changed, and is not smooth scrolling
- if (this.state.value != value && !this.state.isScrolling) {
+ // Call setValue if value has changed
+ if (this.state.value != value) {
this.state.value = value;
this.props.setValue(value);
}
// Do infinite scroll when items length is bigger or equal to viewport
// and isInfiniteScroll is not false.
if (items.length >= viewportSize && isInfiniteScroll) {
// If the scroll position is near the top or bottom, jump back to the middle
@@ -439,20 +431,16 @@ function Spinner(props, context) {
/**
* Smooth scroll to a value based on the index
*
* @param {Number} index: Index number
*/
_smoothScrollToIndex(index) {
const element = this.elements.spinner.children[index];
if (element) {
- // Set the isScrolling flag before smooth scrolling begins
- // and remove it when it has reached the destination.
- // This prevents input box jump when input box changes values
- this.state.isScrolling = true;
element.scrollIntoView({
behavior: "smooth", block: "start"
});
}
},
/**
* Update the selection state.