fa84808048
no issue Since `ember-moment@10.0` it's not been necessary to use the `ember-cli-moment-shim` package, with `moment` instead being usable directly via `ember-auto-import`. Getting rid of the shim package is necessary for compatibility with `embroider`, Ember's new build tooling. - dropped `ember-cli-moment-shim` dependency - added `moment-timezone` dependency and updated all imports to reflect the different package - worked around `ember-power-calendar` having `ember-cli-moment-shim` as a sub-dependency - added empty in-repo-addon `ember-power-calendar-moment` to avoid `ember-power-calendar` complaining about a missing package - added `ember-power-calendar-utils` in-repo-addon that is a copy of `ember-power-calendar-moment` but without the build-time renaming of the tree for better compatibility with embroider
147 lines
3.8 KiB
JavaScript
147 lines
3.8 KiB
JavaScript
import Component from '@glimmer/component';
|
|
import moment from 'moment-timezone';
|
|
import {action} from '@ember/object';
|
|
import {isBlank} from '@ember/utils';
|
|
import {tracked} from '@glimmer/tracking';
|
|
|
|
export class DateError extends Error {
|
|
constructor(msgOrObj) {
|
|
if (typeof msgOrObj === 'string') {
|
|
super(msgOrObj);
|
|
} else {
|
|
super(msgOrObj.message);
|
|
Object.keys(msgOrObj).forEach((key) => {
|
|
if (key !== 'message') {
|
|
this[key] = msgOrObj[key];
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
export default class GhDatePicker extends Component {
|
|
@tracked error = null;
|
|
|
|
get dateFormat() {
|
|
return 'YYYY-MM-DD';
|
|
}
|
|
|
|
get minDate() {
|
|
return this._minMaxMoment(this.args.minDate);
|
|
}
|
|
|
|
get maxDate() {
|
|
return this._minMaxMoment(this.args.maxDate);
|
|
}
|
|
|
|
@action
|
|
setDate(dateStr) {
|
|
this.error = null;
|
|
|
|
if (!dateStr.match(/^\d\d\d\d-\d\d-\d\d$/)) {
|
|
this.error = `Date must be ${this.dateFormat}`;
|
|
this.args.onError?.(new DateError({
|
|
message: this.error,
|
|
date: dateStr
|
|
}));
|
|
return false;
|
|
}
|
|
|
|
const mDate = moment(dateStr);
|
|
|
|
if (!mDate.isValid()) {
|
|
this.error = 'Invalid date';
|
|
this.args.onError?.(new DateError({
|
|
message: this.error,
|
|
date: dateStr
|
|
}));
|
|
return false;
|
|
}
|
|
|
|
if (this.args.minDate && mDate.isBefore(moment(this.args.minDate))) {
|
|
this.error = this.args.minDateError || `Must be on or after ${moment(this.args.minDate).format(this.dateFormat)}`;
|
|
|
|
this.args.onError?.(new DateError({
|
|
message: this.error,
|
|
date: dateStr
|
|
}));
|
|
return false;
|
|
}
|
|
|
|
if (this.args.maxDate && mDate.isAfter(moment(this.args.maxDate))) {
|
|
this.error = this.args.maxDateError || `Must be on or before ${moment(this.args.maxDate).format(this.dateFormat)}`;
|
|
this.args.onError?.(new DateError({
|
|
message: this.error,
|
|
date: dateStr
|
|
}));
|
|
return false;
|
|
}
|
|
|
|
this.args.onChange?.(mDate.toDate());
|
|
}
|
|
|
|
@action
|
|
onDateSelected(datepickerEvent) {
|
|
if (datepickerEvent instanceof moment) {
|
|
this.setDate(datepickerEvent.format(this.dateFormat));
|
|
} else {
|
|
this.setDate(datepickerEvent.id);
|
|
}
|
|
}
|
|
|
|
@action
|
|
onDateInput(datepicker, event) {
|
|
const skipFocus = true;
|
|
datepicker.actions.close(event, skipFocus);
|
|
|
|
this.args.onInput?.(event);
|
|
}
|
|
|
|
@action
|
|
onDateBlur(event) {
|
|
const value = event.target.value;
|
|
|
|
if (!value) {
|
|
this.resetInputValue(event.target);
|
|
} else {
|
|
this.setDate(value);
|
|
}
|
|
|
|
this.args.onBlur?.(event);
|
|
}
|
|
|
|
@action
|
|
onDateKeydown(datepicker, event) {
|
|
if (event.key === 'Escape') {
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
this.resetInputValue(event.target);
|
|
}
|
|
|
|
if (event.key === 'Enter') {
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
this.setDate(event.target.value);
|
|
datepicker.actions.close();
|
|
}
|
|
|
|
this.args.onKeydown?.(event);
|
|
}
|
|
|
|
@action
|
|
resetInputValue(input) {
|
|
input.value = moment(this.args.value).format(this.dateFormat);
|
|
this.error = null;
|
|
}
|
|
|
|
_minMaxMoment(date) {
|
|
if (date === 'now') {
|
|
return moment(moment().format(this.dateFormat));
|
|
} else if (!isBlank(date)) {
|
|
return moment(moment(date).format(this.dateFormat));
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
}
|