@limetech/lime-elements
Version:
232 lines (227 loc) • 8.25 kB
JavaScript
import { r as registerInstance, c as createEvent, h, g as getElement } from './index-2714248e.js';
import { c as createRandomString } from './random-string-355331d3.js';
import { i as isIOSDevice, a as isAndroidDevice } from './device-4fdce119.js';
import './sv-d8302491.js';
import { m as moment } from './moment-fbe0e39e.js';
import { M as MDCTextField } from './component-e6eb55fa.js';
import './_commonjsHelpers-9b95d21f.js';
import './ponyfill-9f1f6cd2.js';
import './component-a531729c.js';
import './component-b934161d.js';
class DateFormatter {
constructor(language = 'en') {
this.language = language;
}
formatDate(date, dateFormat) {
if (date) {
return moment(date).locale(this.getLanguage()).format(dateFormat);
}
return '';
}
parseDate(date, dateFormat) {
if (date) {
return moment(date, dateFormat).toDate();
}
return null;
}
getLanguage() {
if (this.language === 'no') {
return 'nb';
}
return this.language;
}
getDateFormat(type) {
return ({
date: 'L',
time: 'LT',
week: '[w] W GGGG',
month: 'MM/YYYY',
quarter: '[Q]Q YYYY',
year: 'YYYY',
datetime: 'L - LT',
}[type] || 'L - LT');
}
}
const datePickerCss = ":host(limel-date-picker){position:relative}limel-input-field[disabled],limel-input-field[readonly]{pointer-events:none}";
// tslint:disable:no-duplicate-string
const nativeTypeForConsumerType = {
date: 'date',
time: 'time',
// Mobile Safari feature detects as capable of input type `week`,
// but it just displays a non-interactive input
// TODO(ads): remove this when support is decent on iOS!
week: isIOSDevice() ? 'date' : 'week',
month: 'month',
quarter: 'date',
year: 'date',
datetime: 'datetime-local',
default: 'datetime-local',
};
const nativeFormatForType = {
date: 'Y-MM-DD',
time: 'HH:mm',
week: 'GGGG-[W]WW',
month: 'Y-MM',
'datetime-local': 'Y-MM-DD[T]HH:mm',
};
const DatePicker = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.change = createEvent(this, "change", 7);
this.portalId = `date-picker-calendar-${createRandomString()}`;
this.documentClickListener = (event) => {
if (event.composedPath().includes(this.textField)) {
return;
}
const element = document.querySelector(`#${this.portalId}`);
if (!element.contains(event.target)) {
this.hideCalendar();
}
};
this.formatValue = (value) => this.dateFormatter.formatDate(value, this.internalFormat);
this.disabled = false;
this.readonly = false;
this.invalid = false;
this.label = undefined;
this.placeholder = undefined;
this.helperText = undefined;
this.required = false;
this.value = undefined;
this.type = 'datetime';
this.format = undefined;
this.language = 'en';
this.formatter = undefined;
this.internalFormat = undefined;
this.showPortal = false;
this.handleCalendarChange = this.handleCalendarChange.bind(this);
this.handleInputElementChange =
this.handleInputElementChange.bind(this);
this.showCalendar = this.showCalendar.bind(this);
this.dateFormatter = new DateFormatter(this.language);
this.clearValue = this.clearValue.bind(this);
this.hideCalendar = this.hideCalendar.bind(this);
this.onInputClick = this.onInputClick.bind(this);
this.nativeChangeHandler = this.nativeChangeHandler.bind(this);
this.preventBlurFromCalendarContainer =
this.preventBlurFromCalendarContainer.bind(this);
}
componentWillLoad() {
this.useNative = !this.readonly && (isIOSDevice() || isAndroidDevice());
this.updateInternalFormatAndType();
}
componentWillUpdate() {
this.updateInternalFormatAndType();
}
disconnectedCallback() {
this.hideCalendar();
}
render() {
const inputProps = {
onAction: this.clearValue,
};
if (this.value && !this.readonly) {
inputProps.trailingIcon = 'clear_symbol';
}
if (this.useNative) {
return (h("limel-input-field", { disabled: this.disabled, readonly: this.readonly, invalid: this.invalid, label: this.label, helperText: this.helperText, required: this.required, value: this.formatValue(this.value), type: this.nativeType, onChange: this.nativeChangeHandler }));
}
const dropdownZIndex = getComputedStyle(this.host).getPropertyValue('--dropdown-z-index');
const formatter = this.formatter || this.formatValue;
return [
h("limel-input-field", Object.assign({ disabled: this.disabled, readonly: this.readonly, invalid: this.invalid, label: this.label, placeholder: this.placeholder, helperText: this.helperText, required: this.required, value: this.value ? formatter(this.value) : '', onFocus: this.showCalendar, onBlur: this.hideCalendar, onClick: this.onInputClick, onChange: this.handleInputElementChange, ref: (el) => (this.textField = el) }, inputProps)),
h("limel-portal", { containerId: this.portalId, visible: this.showPortal, containerStyle: { 'z-index': dropdownZIndex } }, h("limel-flatpickr-adapter", { format: this.internalFormat, language: this.language, type: this.type, value: this.value, ref: (el) => (this.datePickerCalendar = el), isOpen: this.showPortal, formatter: formatter, onChange: this.handleCalendarChange })),
];
}
updateInternalFormatAndType() {
this.nativeType = nativeTypeForConsumerType[this.type || 'default'];
this.nativeFormat = nativeFormatForType[this.nativeType];
if (this.useNative) {
this.internalFormat = this.nativeFormat;
}
else if (this.formatter || this.format) {
this.internalFormat = this.format;
}
else {
this.internalFormat = this.dateFormatter.getDateFormat(this.type);
}
}
nativeChangeHandler(event) {
event.stopPropagation();
const date = this.dateFormatter.parseDate(event.detail, this.internalFormat);
this.change.emit(date);
}
showCalendar(event) {
this.showPortal = true;
const inputElement = this.textField.shadowRoot.querySelector('input');
setTimeout(() => {
this.datePickerCalendar.inputElement = inputElement;
});
event.stopPropagation();
document.addEventListener('mousedown', this.documentClickListener, {
passive: true,
});
document.addEventListener('blur', this.preventBlurFromCalendarContainer, {
capture: true,
});
}
preventBlurFromCalendarContainer(event) {
// We don't want the input element to lose focus when we pick
// a date in the calendar container.
// This is also required in order to not close the non
// automatically closing pickers (type datetime and time)
// when you pick a value.
if (event.relatedTarget === this.datePickerCalendar) {
event.stopPropagation();
}
}
hideCalendar() {
setTimeout(() => {
this.showPortal = false;
});
document.removeEventListener('mousedown', this.documentClickListener);
document.removeEventListener('blur', this.preventBlurFromCalendarContainer);
if (!this.pickerIsAutoClosing()) {
this.fixFlatpickrFocusBug();
}
}
fixFlatpickrFocusBug() {
// Flatpickr removes the focus from the input field
// but the 'visual focus' is still there
const mdcTextField = new MDCTextField(this.textField.shadowRoot.querySelector('.mdc-text-field'));
mdcTextField.getDefaultFoundation().deactivateFocus();
mdcTextField.valid = !this.invalid;
}
handleCalendarChange(event) {
const date = event.detail;
event.stopPropagation();
if (this.pickerIsAutoClosing()) {
this.hideCalendar();
}
this.change.emit(date);
}
onInputClick(event) {
if (this.disabled || this.readonly) {
return;
}
if (this.showPortal) {
return;
}
this.showCalendar(event);
}
handleInputElementChange(event) {
if (event.detail === '') {
this.clearValue();
}
event.stopPropagation();
}
pickerIsAutoClosing() {
return this.type !== 'datetime' && this.type !== 'time';
}
clearValue() {
this.change.emit(null);
}
get host() { return getElement(this); }
};
DatePicker.style = datePickerCss;
export { DatePicker as limel_date_picker };
//# sourceMappingURL=limel-date-picker.entry.js.map