mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
Bug 1363672 - Add step support to date picker
This commit is contained in:
parent
a1c4899124
commit
1cca8d40f3
5 changed files with 64 additions and 18 deletions
|
|
@ -1728,9 +1728,10 @@ let DateTimePickerListener = {
|
||||||
// element's value.
|
// element's value.
|
||||||
value: Object.keys(value).length > 0 ? value
|
value: Object.keys(value).length > 0 ? value
|
||||||
: this._inputElement.value,
|
: this._inputElement.value,
|
||||||
step: this._inputElement.step,
|
|
||||||
min: this._inputElement.min,
|
min: this._inputElement.min,
|
||||||
max: this._inputElement.max,
|
max: this._inputElement.max,
|
||||||
|
step: this._inputElement.getStep(),
|
||||||
|
stepBase: this._inputElement.getStepBase(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -45,18 +45,21 @@ function DateKeeper(props) {
|
||||||
* @param {Number} day
|
* @param {Number} day
|
||||||
* @param {String} min
|
* @param {String} min
|
||||||
* @param {String} max
|
* @param {String} max
|
||||||
|
* @param {Number} step
|
||||||
|
* @param {Number} stepBase
|
||||||
* @param {Number} firstDayOfWeek
|
* @param {Number} firstDayOfWeek
|
||||||
* @param {Array<Number>} weekends
|
* @param {Array<Number>} weekends
|
||||||
* @param {Number} calViewSize
|
* @param {Number} calViewSize
|
||||||
*/
|
*/
|
||||||
init({ year, month, day, min, max, firstDayOfWeek = 0, weekends = [0], calViewSize = 42 }) {
|
init({ year, month, day, min, max, step, stepBase, firstDayOfWeek = 0, weekends = [0], calViewSize = 42 }) {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const isDateSet = year != undefined && month != undefined && day != undefined;
|
const isDateSet = year != undefined && month != undefined && day != undefined;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
firstDayOfWeek, weekends, calViewSize,
|
step, firstDayOfWeek, weekends, calViewSize,
|
||||||
min: new Date(min != undefined ? min : MIN_DATE),
|
min: new Date(min != undefined ? min : MIN_DATE),
|
||||||
max: new Date(max != undefined ? max : MAX_DATE),
|
max: new Date(max != undefined ? max : MAX_DATE),
|
||||||
|
stepBase: new Date(stepBase),
|
||||||
today: this._newUTCDate(today.getFullYear(), today.getMonth(), today.getDate()),
|
today: this._newUTCDate(today.getFullYear(), today.getMonth(), today.getDate()),
|
||||||
weekHeaders: this._getWeekHeaders(firstDayOfWeek, weekends),
|
weekHeaders: this._getWeekHeaders(firstDayOfWeek, weekends),
|
||||||
years: [],
|
years: [],
|
||||||
|
|
@ -192,33 +195,50 @@ function DateKeeper(props) {
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
getDays() {
|
getDays() {
|
||||||
// TODO: add step support
|
|
||||||
const firstDayOfMonth = this._getFirstCalendarDate(this.state.dateObj, this.state.firstDayOfWeek);
|
const firstDayOfMonth = this._getFirstCalendarDate(this.state.dateObj, this.state.firstDayOfWeek);
|
||||||
const month = this.month;
|
const month = this.month;
|
||||||
let days = [];
|
let days = [];
|
||||||
|
|
||||||
for (let i = 0; i < this.state.calViewSize; i++) {
|
for (let i = 0; i < this.state.calViewSize; i++) {
|
||||||
const dateObj = this._newUTCDate(firstDayOfMonth.getUTCFullYear(), firstDayOfMonth.getUTCMonth(), firstDayOfMonth.getUTCDate() + i);
|
const dateObj = this._newUTCDate(firstDayOfMonth.getUTCFullYear(),
|
||||||
|
firstDayOfMonth.getUTCMonth(),
|
||||||
|
firstDayOfMonth.getUTCDate() + i);
|
||||||
let classNames = [];
|
let classNames = [];
|
||||||
let enabled = true;
|
let enabled = true;
|
||||||
if (this.state.weekends.includes(dateObj.getUTCDay())) {
|
|
||||||
|
const isWeekend = this.state.weekends.includes(dateObj.getUTCDay());
|
||||||
|
const isCurrentMonth = month == dateObj.getUTCMonth();
|
||||||
|
const isSelection = this.state.selection.year == dateObj.getUTCFullYear() &&
|
||||||
|
this.state.selection.month == dateObj.getUTCMonth() &&
|
||||||
|
this.state.selection.day == dateObj.getUTCDate();
|
||||||
|
const isOutOfRange = dateObj.getTime() < this.state.min.getTime() ||
|
||||||
|
dateObj.getTime() > this.state.max.getTime();
|
||||||
|
const isToday = this.state.today.getTime() == dateObj.getTime();
|
||||||
|
const isOffStep = this._checkIsOffStep(dateObj,
|
||||||
|
this._newUTCDate(dateObj.getUTCFullYear(),
|
||||||
|
dateObj.getUTCMonth(),
|
||||||
|
dateObj.getUTCDate() + 1));
|
||||||
|
|
||||||
|
if (isWeekend) {
|
||||||
classNames.push("weekend");
|
classNames.push("weekend");
|
||||||
}
|
}
|
||||||
if (month != dateObj.getUTCMonth()) {
|
if (!isCurrentMonth) {
|
||||||
classNames.push("outside");
|
classNames.push("outside");
|
||||||
}
|
}
|
||||||
if (this.state.selection.year == dateObj.getUTCFullYear() &&
|
if (isSelection && !isOutOfRange && !isOffStep) {
|
||||||
this.state.selection.month == dateObj.getUTCMonth() &&
|
|
||||||
this.state.selection.day == dateObj.getUTCDate()) {
|
|
||||||
classNames.push("selection");
|
classNames.push("selection");
|
||||||
}
|
}
|
||||||
if (dateObj.getTime() < this.state.min.getTime() || dateObj.getTime() > this.state.max.getTime()) {
|
if (isOutOfRange) {
|
||||||
classNames.push("out-of-range");
|
classNames.push("out-of-range");
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
}
|
||||||
if (this.state.today.getTime() == dateObj.getTime()) {
|
if (isToday) {
|
||||||
classNames.push("today");
|
classNames.push("today");
|
||||||
}
|
}
|
||||||
|
if (isOffStep) {
|
||||||
|
classNames.push("off-step");
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
days.push({
|
days.push({
|
||||||
dateObj,
|
dateObj,
|
||||||
classNames,
|
classNames,
|
||||||
|
|
@ -228,6 +248,24 @@ function DateKeeper(props) {
|
||||||
return days;
|
return days;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a date is off step given a starting point and the next increment
|
||||||
|
* @param {Date} start
|
||||||
|
* @param {Date} next
|
||||||
|
* @return {Boolean}
|
||||||
|
*/
|
||||||
|
_checkIsOffStep(start, next) {
|
||||||
|
// If the increment is larger or equal to the step, it must not be off-step.
|
||||||
|
if (next - start >= this.state.step) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Calculate the last valid date
|
||||||
|
const lastValidStep = Math.floor((next - 1 - this.state.stepBase) / this.state.step);
|
||||||
|
const lastValidTimeInMs = lastValidStep * this.state.step + this.state.stepBase.getTime();
|
||||||
|
// The date is off-step if the last valid date is smaller than the start date
|
||||||
|
return lastValidTimeInMs < start.getTime();
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get week headers for calendar
|
* Get week headers for calendar
|
||||||
* @param {Number} firstDayOfWeek
|
* @param {Number} firstDayOfWeek
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ function DatePicker(context) {
|
||||||
* {Number} date [optional]
|
* {Number} date [optional]
|
||||||
* {String} min
|
* {String} min
|
||||||
* {String} max
|
* {String} max
|
||||||
|
* {Number} step
|
||||||
|
* {Number} stepBase
|
||||||
* {Number} firstDayOfWeek
|
* {Number} firstDayOfWeek
|
||||||
* {Array<Number>} weekends
|
* {Array<Number>} weekends
|
||||||
* {Array<String>} monthStrings
|
* {Array<String>} monthStrings
|
||||||
|
|
@ -41,10 +43,10 @@ function DatePicker(context) {
|
||||||
* Set initial date picker states.
|
* Set initial date picker states.
|
||||||
*/
|
*/
|
||||||
_setDefaultState() {
|
_setDefaultState() {
|
||||||
const { year, month, day, min, max, firstDayOfWeek, weekends,
|
const { year, month, day, min, max, step, stepBase, firstDayOfWeek, weekends,
|
||||||
monthStrings, weekdayStrings, locale } = this.props;
|
monthStrings, weekdayStrings, locale } = this.props;
|
||||||
const dateKeeper = new DateKeeper({
|
const dateKeeper = new DateKeeper({
|
||||||
year, month, day, min, max, firstDayOfWeek, weekends,
|
year, month, day, min, max, step, stepBase, firstDayOfWeek, weekends,
|
||||||
calViewSize: CAL_VIEW_SIZE
|
calViewSize: CAL_VIEW_SIZE
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,8 @@
|
||||||
locale,
|
locale,
|
||||||
min: detail.min,
|
min: detail.min,
|
||||||
max: detail.max,
|
max: detail.max,
|
||||||
|
step: detail.step,
|
||||||
|
stepBase: detail.stepBase,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -232,12 +232,14 @@ button.month-year.active::after {
|
||||||
color: var(--weekend-outside-font-color);
|
color: var(--weekend-outside-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.days-view > .out-of-range {
|
.days-view > .out-of-range,
|
||||||
|
.days-view > .off-step {
|
||||||
color: var(--weekday-disabled-font-color);
|
color: var(--weekday-disabled-font-color);
|
||||||
background: var(--disabled-fill-color);
|
background: var(--disabled-fill-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.days-view > .out-of-range.weekend {
|
.days-view > .out-of-range.weekend,
|
||||||
|
.days-view > .off-step.weekend {
|
||||||
color: var(--weekend-disabled-font-color);
|
color: var(--weekend-disabled-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -245,7 +247,8 @@ button.month-year.active::after {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.days-view > .out-of-range::before {
|
.days-view > .out-of-range::before,
|
||||||
|
.days-view > .off-step::before {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,7 +344,7 @@ button.month-year.active::after {
|
||||||
}
|
}
|
||||||
|
|
||||||
.spinner-container > .spinner:not(.scrolling) > div.selection,
|
.spinner-container > .spinner:not(.scrolling) > div.selection,
|
||||||
.calendar-container .days-view > div.selection:not(.out-of-range) {
|
.calendar-container .days-view > div.selection {
|
||||||
color: var(--selected-font-color);
|
color: var(--selected-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue