UNPKG

igniteui-webcomponents

Version:

Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.

460 lines 16.7 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { html } from 'lit'; import { eventOptions, property } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { live } from 'lit/directives/live.js'; import { convertToDate } from '../calendar/helpers.js'; import { addKeybindings, arrowDown, arrowLeft, arrowRight, arrowUp, ctrlKey, } from '../common/controllers/key-bindings.js'; import { watch } from '../common/decorators/watch.js'; import { registerComponent } from '../common/definitions/register.js'; import { EventEmitterMixin } from '../common/mixins/event-emitter.js'; import { FormValueDateTimeTransformers } from '../common/mixins/forms/form-transformers.js'; import { createFormValueState } from '../common/mixins/forms/form-value.js'; import { partMap } from '../common/part-map.js'; import { IgcMaskInputBaseComponent, } from '../mask-input/mask-input-base.js'; import IgcValidationContainerComponent from '../validation-container/validation-container.js'; import { DatePart, DateParts, DateTimeUtil, } from './date-util.js'; import { dateTimeInputValidators } from './validators.js'; class IgcDateTimeInputComponent extends EventEmitterMixin(IgcMaskInputBaseComponent) { static register() { registerComponent(IgcDateTimeInputComponent, IgcValidationContainerComponent); } get __validators() { return dateTimeInputValidators; } get inputFormat() { return this._inputFormat || this._defaultMask; } set inputFormat(val) { if (val) { this.setMask(val); this._inputFormat = val; if (this.value) { this.updateMask(); } } } get value() { return this._formValue.value; } set value(value) { this._formValue.setValueAndFormState(value); this.updateMask(); } set min(value) { this._min = convertToDate(value); this._validate(); } get min() { return this._min; } set max(value) { this._max = convertToDate(value); this._validate(); } get max() { return this._max; } setDefaultMask() { if (!this._inputFormat) { this.updateDefaultMask(); this.setMask(this._defaultMask); } if (this.value) { this.updateMask(); } } setDisplayFormat() { if (this.value) { this.updateMask(); } } promptChange() { if (!this.prompt) { this.prompt = this.parser.prompt; } else { this.parser.prompt = this.prompt; } } get hasDateParts() { const parts = this._inputDateParts || DateTimeUtil.parseDateTimeFormat(this.inputFormat); return parts.some((p) => p.type === DateParts.Date || p.type === DateParts.Month || p.type === DateParts.Year); } get hasTimeParts() { const parts = this._inputDateParts || DateTimeUtil.parseDateTimeFormat(this.inputFormat); return parts.some((p) => p.type === DateParts.Hours || p.type === DateParts.Minutes || p.type === DateParts.Seconds); } get targetDatePart() { let result; if (this.focused) { const partType = this._inputDateParts.find((p) => p.start <= this.inputSelection.start && this.inputSelection.start <= p.end && p.type !== DateParts.Literal)?.type; if (partType) { result = partType; } } else if (this._inputDateParts.some((p) => p.type === DateParts.Date)) { result = DatePart.Date; } else if (this._inputDateParts.some((p) => p.type === DateParts.Hours)) { result = DatePart.Hours; } else { result = this._inputDateParts[0].type; } return result; } get datePartDeltas() { return Object.assign({}, this._datePartDeltas, this.spinDelta); } constructor() { super(); this._formValue = createFormValueState(this, { initialValue: null, transformers: FormValueDateTimeTransformers, }); this._oldValue = null; this._min = null; this._max = null; this._datePartDeltas = { date: 1, month: 1, year: 1, hours: 1, minutes: 1, seconds: 1, }; this.spinLoop = true; this.locale = 'en'; addKeybindings(this, { skip: () => this.readOnly, bindingDefaults: { preventDefault: true, triggers: ['keydownRepeat'] }, }) .set([ctrlKey, ';'], this.setToday) .set(arrowUp, this.keyboardSpin.bind(this, 'up')) .set(arrowDown, this.keyboardSpin.bind(this, 'down')) .set([ctrlKey, arrowLeft], this.navigateParts.bind(this, 0)) .set([ctrlKey, arrowRight], this.navigateParts.bind(this, 1)); } connectedCallback() { super.connectedCallback(); this.updateDefaultMask(); this.setMask(this.inputFormat); if (this.value) { this.updateMask(); } } stepUp(datePart, delta) { const targetPart = datePart || this.targetDatePart; if (!targetPart) { return; } const { start, end } = this.inputSelection; const newValue = this.trySpinValue(targetPart, delta); this.value = newValue; this.updateComplete.then(() => this.input.setSelectionRange(start, end)); } stepDown(datePart, delta) { const targetPart = datePart || this.targetDatePart; if (!targetPart) { return; } const { start, end } = this.inputSelection; const newValue = this.trySpinValue(targetPart, delta, true); this.value = newValue; this.updateComplete.then(() => this.input.setSelectionRange(start, end)); } clear() { this.maskedValue = ''; this.value = null; } setToday() { this.value = new Date(); this.handleInput(); } updateMask() { if (this.focused) { this.maskedValue = this.getMaskedValue(); } else { if (!DateTimeUtil.isValidDate(this.value)) { this.maskedValue = ''; return; } const format = this.displayFormat || this.inputFormat; if (this.displayFormat) { this.maskedValue = DateTimeUtil.formatDate(this.value, this.locale, format, true); } else if (this.inputFormat) { this.maskedValue = DateTimeUtil.formatDate(this.value, this.locale, format); } else { this.maskedValue = this.value.toLocaleString(); } } } handleInput() { this._setTouchedState(); this.emitEvent('igcInput', { detail: this.value?.toString() }); } handleDragLeave() { if (!this.focused) { this.updateMask(); } } handleDragEnter() { if (!this.focused) { this.maskedValue = this.getMaskedValue(); } } async updateInput(string, range) { const { value, end } = this.parser.replace(this.maskedValue, string, range.start, range.end); this.maskedValue = value; this.updateValue(); this.requestUpdate(); if (range.start !== this.inputFormat.length) { this.handleInput(); } await this.updateComplete; this.input.setSelectionRange(end, end); } trySpinValue(datePart, delta, negative = false) { const _delta = delta || this.datePartDeltas[datePart] || 1; const spinValue = negative ? -Math.abs(_delta) : Math.abs(_delta); return this.spinValue(datePart, spinValue); } spinValue(datePart, delta) { if (!(this.value && DateTimeUtil.isValidDate(this.value))) { return new Date(); } const newDate = new Date(this.value.getTime()); let formatPart; let amPmFromMask; switch (datePart) { case DatePart.Date: DateTimeUtil.spinDate(delta, newDate, this.spinLoop); break; case DatePart.Month: DateTimeUtil.spinMonth(delta, newDate, this.spinLoop); break; case DatePart.Year: DateTimeUtil.spinYear(delta, newDate); break; case DatePart.Hours: DateTimeUtil.spinHours(delta, newDate, this.spinLoop); break; case DatePart.Minutes: DateTimeUtil.spinMinutes(delta, newDate, this.spinLoop); break; case DatePart.Seconds: DateTimeUtil.spinSeconds(delta, newDate, this.spinLoop); break; case DatePart.AmPm: formatPart = this._inputDateParts.find((dp) => dp.type === DateParts.AmPm); if (formatPart !== undefined) { amPmFromMask = this.maskedValue.substring(formatPart.start, formatPart.end); return DateTimeUtil.spinAmPm(newDate, this.value, amPmFromMask); } break; } return newDate; } async onWheel(event) { if (!this.focused || this.readOnly) { return; } event.preventDefault(); event.stopPropagation(); const { start, end } = this.inputSelection; event.deltaY > 0 ? this.stepDown() : this.stepUp(); this.handleInput(); await this.updateComplete; this.setSelectionRange(start, end); } updateDefaultMask() { this._defaultMask = DateTimeUtil.getDefaultMask(this.locale); } setMask(string) { const oldFormat = this._inputDateParts?.map((p) => p.format).join(''); this._inputDateParts = DateTimeUtil.parseDateTimeFormat(string); const value = this._inputDateParts.map((p) => p.format).join(''); this._defaultMask = value; const newMask = (value || DateTimeUtil.DEFAULT_INPUT_FORMAT).replace(new RegExp(/(?=[^t])[\w]/, 'g'), '0'); this._mask = newMask.includes('tt') ? newMask.replace(/tt/g, 'LL') : newMask; this.parser.mask = this._mask; this.parser.prompt = this.prompt; if (!this.placeholder || oldFormat === this.placeholder) { this.placeholder = value; } } parseDate(val) { return val ? DateTimeUtil.parseValueFromMask(val, this._inputDateParts, this.prompt) : null; } getMaskedValue() { let mask = this.emptyMask; if (DateTimeUtil.isValidDate(this.value)) { for (const part of this._inputDateParts) { if (part.type === DateParts.Literal) { continue; } const targetValue = DateTimeUtil.getPartValue(part, part.format.length, this.value); mask = this.parser.replace(mask, targetValue, part.start, part.end).value; } return mask; } return this.maskedValue === '' ? mask : this.maskedValue; } isComplete() { return !this.maskedValue.includes(this.prompt); } updateValue() { if (this.isComplete()) { const parsedDate = this.parseDate(this.maskedValue); this.value = DateTimeUtil.isValidDate(parsedDate) ? parsedDate : null; } else { this.value = null; } } _updateSetRangeTextValue() { this.updateValue(); } getNewPosition(value, direction = 0) { const cursorPos = this.selection.start; if (!direction) { const part = this._inputDateParts.findLast((part) => part.type === DateParts.Literal && part.end < cursorPos); return part?.end ?? 0; } const part = this._inputDateParts.find((part) => part.type === DateParts.Literal && part.start > cursorPos); return part?.start ?? value.length; } async handleFocus() { this.focused = true; if (this.readOnly) { return; } this._oldValue = this.value; const areFormatsDifferent = this.displayFormat !== this.inputFormat; if (!this.value) { this.maskedValue = this.emptyMask; await this.updateComplete; this.select(); } else if (areFormatsDifferent) { this.updateMask(); } } handleBlur() { const isEmptyMask = this.maskedValue === this.emptyMask; this.focused = false; if (!(this.isComplete() || isEmptyMask)) { const parse = this.parseDate(this.maskedValue); if (parse) { this.value = parse; } else { this.value = null; this.maskedValue = ''; } } else { this.updateMask(); } const isSameValue = this._oldValue === this.value; if (!(this.readOnly || isSameValue)) { this.emitEvent('igcChange', { detail: this.value }); } super._handleBlur(); } navigateParts(delta) { const position = this.getNewPosition(this.input.value, delta); this.setSelectionRange(position, position); } async keyboardSpin(direction) { direction === 'up' ? this.stepUp() : this.stepDown(); this.handleInput(); await this.updateComplete; this.setSelectionRange(this.selection.start, this.selection.end); } renderInput() { return html ` <input type="text" part=${partMap(this.resolvePartNames('input'))} name=${ifDefined(this.name)} .value=${live(this.maskedValue)} .placeholder=${live(this.placeholder || this.emptyMask)} ?readonly=${this.readOnly} ?disabled=${this.disabled} @blur=${this.handleBlur} @focus=${this.handleFocus} @input=${super.handleInput} @wheel=${this.onWheel} @keydown=${super.handleKeydown} @click=${this.handleClick} @cut=${this.handleCut} @compositionstart=${this.handleCompositionStart} @compositionend=${this.handleCompositionEnd} @dragenter=${this.handleDragEnter} @dragleave=${this.handleDragLeave} @dragstart=${this.handleDragStart} /> `; } } IgcDateTimeInputComponent.tagName = 'igc-date-time-input'; export default IgcDateTimeInputComponent; __decorate([ property({ attribute: 'input-format' }) ], IgcDateTimeInputComponent.prototype, "inputFormat", null); __decorate([ property({ converter: convertToDate }) ], IgcDateTimeInputComponent.prototype, "value", null); __decorate([ property({ converter: convertToDate }) ], IgcDateTimeInputComponent.prototype, "min", null); __decorate([ property({ converter: convertToDate }) ], IgcDateTimeInputComponent.prototype, "max", null); __decorate([ property({ attribute: 'display-format' }) ], IgcDateTimeInputComponent.prototype, "displayFormat", void 0); __decorate([ property({ attribute: false }) ], IgcDateTimeInputComponent.prototype, "spinDelta", void 0); __decorate([ property({ type: Boolean, attribute: 'spin-loop' }) ], IgcDateTimeInputComponent.prototype, "spinLoop", void 0); __decorate([ property() ], IgcDateTimeInputComponent.prototype, "locale", void 0); __decorate([ watch('locale', { waitUntilFirstUpdate: true }) ], IgcDateTimeInputComponent.prototype, "setDefaultMask", null); __decorate([ watch('displayFormat', { waitUntilFirstUpdate: true }) ], IgcDateTimeInputComponent.prototype, "setDisplayFormat", null); __decorate([ watch('prompt', { waitUntilFirstUpdate: true }) ], IgcDateTimeInputComponent.prototype, "promptChange", null); __decorate([ eventOptions({ passive: false }) ], IgcDateTimeInputComponent.prototype, "onWheel", null); //# sourceMappingURL=date-time-input.js.map