UNPKG

@kelvininc/ui-components

Version:
498 lines (497 loc) 25.5 kB
import { Host, h } from "@stencil/core"; import { EAbsoluteTimePickerMode, EIconName, EInputSource } from "../../types"; import { EDateTimeInputTypeStyle } from "../date-time-input/date-time-input.types"; import { CALENDAR_DATE_FORMAT, DATE_FORMAT, DATE_TIME_INPUT_DATE_FORMAT, DEFAULT_LEFT_INPUT_CONFIG, DEFAULT_RIGHT_INPUT_CONFIG, EMPTY_INPUT_PLACEHOLDER, INPUT_MASK_PLACEHOLDER } from "./absolute-time-picker-dropdown-input.config"; import dayjs from "dayjs"; import { fromISO, getDefaultTimezoneSettings } from "../../utils/date"; import { getFirstCalendarInitialDate, getSecondCalendarInitialDate } from "../absolute-time-picker/absolute-time-picker.helper"; import { isEmpty, isNumber } from "lodash-es"; import { getRangeCalendarDates, getRangeInputValues, getSingleCalendarDate, getSingleInputDate } from "./absolute-time-picker-dropdown-input.utils"; export class KvAbsoluteTimePickerDropdownInput { constructor() { /** @inheritdoc */ this.timezone = getDefaultTimezoneSettings(); /** @inheritdoc */ this.mode = EAbsoluteTimePickerMode.Range; /** @inheritdoc */ this.isDropdownOpen = false; /** @inheritdoc */ this.disabled = false; this.singleTimeInputValue = ''; this.displayedMonth = isNumber(this.initialDate) ? dayjs(this.initialDate) : dayjs(); /** Shared hovered date between calendars for range mode */ this.hoveredDate = ''; this.handleInputFocus = (source) => { this.focusedInput = source; if (!this.isDropdownOpen) { this.isDropdownOpen = true; this.dropdownStateChange.emit(this.isDropdownOpen); } }; this.getValidSelectedRangeFromUserClick = (parsedDate) => { var _a, _b, _c, _d; if (this.focusedInput === EInputSource.From) { if (isNumber(this.minimumFromInputDate) && parsedDate.isBefore(this.minimumFromInputDate)) { return Object.assign(Object.assign({}, this.rangeInputValues), { from: dayjs(this.minimumFromInputDate).format(DATE_FORMAT) }); } if (!isEmpty((_a = this.rangeInputValues) === null || _a === void 0 ? void 0 : _a.to) && dayjs((_b = this.rangeInputValues) === null || _b === void 0 ? void 0 : _b.to, DATE_FORMAT).isBefore(parsedDate)) { return { from: parsedDate.format(DATE_FORMAT), to: parsedDate.format(DATE_FORMAT) }; } return Object.assign(Object.assign({}, this.rangeInputValues), { from: parsedDate.format(DATE_FORMAT) }); } else { if (isNumber(this.minimumToInputDate) && parsedDate.isBefore(this.minimumToInputDate)) { return Object.assign(Object.assign({}, this.rangeInputValues), { to: dayjs(this.minimumToInputDate).format(DATE_FORMAT) }); } if (!isEmpty((_c = this.rangeInputValues) === null || _c === void 0 ? void 0 : _c.from) && dayjs((_d = this.rangeInputValues) === null || _d === void 0 ? void 0 : _d.from, DATE_FORMAT).isAfter(parsedDate)) { return { from: parsedDate.format(DATE_FORMAT), to: parsedDate.format(DATE_FORMAT) }; } return Object.assign(Object.assign({}, this.rangeInputValues), { to: parsedDate.format(DATE_FORMAT) }); } }; this.onClickDate = ({ detail }) => { var _a, _b; let clickedDate = fromISO(detail.date); if (this.mode === EAbsoluteTimePickerMode.Single) { if (isNumber(this.minimumSingleInputDate) && dayjs(clickedDate).isBefore(this.minimumSingleInputDate)) { clickedDate = dayjs(this.minimumSingleInputDate); } this.singleTimeInputValue = clickedDate.format(DATE_FORMAT); return; } const validSelectedRange = this.getValidSelectedRangeFromUserClick(clickedDate); this.rangeInputValues = validSelectedRange; if (this.focusedInput === EInputSource.From && isEmpty((_a = this.rangeInputValues) === null || _a === void 0 ? void 0 : _a.to)) { this.focusedInput = EInputSource.To; } if (this.focusedInput === EInputSource.To && isEmpty((_b = this.rangeInputValues) === null || _b === void 0 ? void 0 : _b.from)) { this.focusedInput = EInputSource.From; } }; this.handleEmptyTextChange = () => { if (this.mode === EAbsoluteTimePickerMode.Single) { this.singleTimeInputValue = ''; } else { if (this.focusedInput === EInputSource.From) { this.rangeInputValues = Object.assign(Object.assign({}, this.rangeInputValues), { from: '' }); } else { this.rangeInputValues = Object.assign(Object.assign({}, this.rangeInputValues), { to: '' }); } } }; this.hanleOnTextChange = (event) => { const parsedDateTime = dayjs(event.detail, DATE_FORMAT); if (isEmpty(event.detail)) { this.handleEmptyTextChange(); return; } if (parsedDateTime.isValid()) { if (this.mode === EAbsoluteTimePickerMode.Single) { this.singleTimeInputValue = parsedDateTime.format(DATE_FORMAT); this.displayedMonth = parsedDateTime; return; } if (this.focusedInput === EInputSource.From) { this.rangeInputValues = Object.assign(Object.assign({}, this.rangeInputValues), { from: parsedDateTime.format(DATE_FORMAT) }); } else { this.rangeInputValues = Object.assign(Object.assign({}, this.rangeInputValues), { to: parsedDateTime.format(DATE_FORMAT) }); } this.displayedMonth = parsedDateTime; } }; this.handleClickBackMonth = () => { this.displayedMonth = this.displayedMonth.subtract(1, 'month'); }; this.handleClickForwardMonth = () => { this.displayedMonth = this.displayedMonth.add(1, 'month'); }; this.handleHoveredDateChange = (event) => { if (this.mode === EAbsoluteTimePickerMode.Range) this.hoveredDate = event.detail; }; this.handleCloseDropdown = () => { var _a, _b; this.isDropdownOpen = false; this.focusedInput = null; if (this.mode === EAbsoluteTimePickerMode.Single) { if (isEmpty(this.singleTimeInputValue)) { this.syncSelectedTimeState(this.selectedTime); } else { this.selectedTimeChange.emit([dayjs(this.singleTimeInputValue, DATE_FORMAT).tz(this.timezone.name, true).valueOf()]); } } else { if (isEmpty((_a = this.rangeInputValues) === null || _a === void 0 ? void 0 : _a.from) || isEmpty((_b = this.rangeInputValues) === null || _b === void 0 ? void 0 : _b.to)) { this.syncSelectedTimeState(this.selectedTime); } else { this.selectedTimeChange.emit([ dayjs(this.rangeInputValues.from, DATE_FORMAT).tz(this.timezone.name, true).valueOf(), dayjs(this.rangeInputValues.to, DATE_FORMAT).tz(this.timezone.name, true).valueOf() ]); } } this.dropdownStateChange.emit(this.isDropdownOpen); }; this.handleDropdownArrowClick = () => { const previousDropdownState = this.isDropdownOpen; // Dropdown was open, we need to handle the time state update and close the dropdown if (previousDropdownState) { this.handleCloseDropdown(); } else { this.isDropdownOpen = true; this.focusedInput = this.mode === EAbsoluteTimePickerMode.Single ? EInputSource.Single : EInputSource.To; this.dropdownStateChange.emit(this.isDropdownOpen); } }; this.isHoveringStylingActive = () => { var _a, _b; return (!isEmpty((_a = this.rangeInputValues) === null || _a === void 0 ? void 0 : _a.from) && this.focusedInput === EInputSource.To) || (!isEmpty((_b = this.rangeInputValues) === null || _b === void 0 ? void 0 : _b.to) && this.focusedInput === EInputSource.From); }; this.getMinimumCalendarDate = () => { return this.mode === EAbsoluteTimePickerMode.Single ? isNumber(this.minimumSingleInputDate) && dayjs(this.minimumSingleInputDate).format(CALENDAR_DATE_FORMAT) : isNumber(this.minimumFromInputDate) && dayjs(this.minimumFromInputDate).format(CALENDAR_DATE_FORMAT); }; this.getSelectedCalendarDates = () => { const inputDate = this.mode === EAbsoluteTimePickerMode.Single ? getSingleCalendarDate(this.singleTimeInputValue) : getRangeCalendarDates(this.rangeInputValues); if (inputDate) return inputDate; if (this.selectedTime) { return this.mode === EAbsoluteTimePickerMode.Single ? getSingleCalendarDate(getSingleInputDate(this.selectedTime, this.timezone.name)) : getRangeCalendarDates(getRangeInputValues(this.selectedTime, this.timezone.name)); } return []; }; } componentWillLoad() { this.syncSelectedTimeState(this.selectedTime); } handleSelectedTimeChange(newValue) { this.syncSelectedTimeState(newValue); } syncSelectedTimeState(newValue) { if (this.mode === EAbsoluteTimePickerMode.Single) { this.singleTimeInputValue = getSingleInputDate(newValue, this.timezone.name); } else { this.rangeInputValues = getRangeInputValues(newValue, this.timezone.name); } } render() { var _a, _b; const fromCalendarInitialDate = getFirstCalendarInitialDate(this.displayedMonth); const toCalendarInitialDate = getSecondCalendarInitialDate(this.displayedMonth); const selectedDates = this.getSelectedCalendarDates(); const useFromInputInputMask = this.focusedInput === EInputSource.From; const useToInputInputMask = this.focusedInput === EInputSource.To; const useSingleInputInputMask = this.focusedInput === EInputSource.Single; const isHoveringStyleEnabled = this.isHoveringStylingActive(); const minimumCalendarDate = this.getMinimumCalendarDate(); return (h(Host, { key: '2460d2e8ab558c6d64e6b4148d232e374f50a235' }, h("kv-dropdown-base", { key: '8556ff31672fb6a9438a65cb8ac2b2cbddad29ea', isOpen: this.isDropdownOpen, onClickOutside: this.handleCloseDropdown }, h("slot", { key: '6fd559cf83df7bfd58cfb7ae8760d6dd0194d11f', name: "dropdown-action", slot: "action" }, this.mode === EAbsoluteTimePickerMode.Range ? (h("div", { class: "time-range-input-container" }, h("kv-date-time-input", Object.assign({ disabled: this.disabled, inputStyleType: EDateTimeInputTypeStyle.MergedLeft, value: (_a = this.rangeInputValues) === null || _a === void 0 ? void 0 : _a.from, dateFormat: DATE_TIME_INPUT_DATE_FORMAT, placeholder: useFromInputInputMask ? INPUT_MASK_PLACEHOLDER : EMPTY_INPUT_PLACEHOLDER, useInputMask: useFromInputInputMask, onInputFocus: () => this.handleInputFocus(EInputSource.From), forcedFocus: this.focusedInput === EInputSource.From && this.isDropdownOpen, onTextChange: this.hanleOnTextChange }, DEFAULT_LEFT_INPUT_CONFIG)), h("kv-date-time-input", Object.assign({ disabled: this.disabled, inputStyleType: EDateTimeInputTypeStyle.MergedRight, value: (_b = this.rangeInputValues) === null || _b === void 0 ? void 0 : _b.to, dateFormat: DATE_TIME_INPUT_DATE_FORMAT, placeholder: useToInputInputMask ? INPUT_MASK_PLACEHOLDER : EMPTY_INPUT_PLACEHOLDER, useInputMask: useToInputInputMask, onInputFocus: () => this.handleInputFocus(EInputSource.To), forcedFocus: this.focusedInput === EInputSource.To && this.isDropdownOpen, rightIcon: this.isDropdownOpen ? EIconName.ArrowDropUp : EIconName.ArrowDropDown, onTextChange: this.hanleOnTextChange, onRightIconClick: this.handleDropdownArrowClick }, DEFAULT_RIGHT_INPUT_CONFIG)))) : (h("div", { class: "single-input-container" }, h("kv-date-time-input", Object.assign({ disabled: this.disabled, value: this.singleTimeInputValue, dateFormat: DATE_TIME_INPUT_DATE_FORMAT, placeholder: useSingleInputInputMask ? INPUT_MASK_PLACEHOLDER : EMPTY_INPUT_PLACEHOLDER, useInputMask: useSingleInputInputMask, forcedFocus: this.focusedInput === EInputSource.Single && this.isDropdownOpen, onInputFocus: () => this.handleInputFocus(EInputSource.Single), inputStyleType: EDateTimeInputTypeStyle.Separated, rightIcon: this.isDropdownOpen ? EIconName.ArrowDropUp : EIconName.ArrowDropDown, onTextChange: this.hanleOnTextChange, onRightIconClick: this.handleDropdownArrowClick }, DEFAULT_LEFT_INPUT_CONFIG))))), h("div", { key: '4c3775d051bf21b6b00edef7cdeb3916fde9c072', slot: "list" }, h("div", { key: '32ed07881274b42003e22f12e4f3a91faa49d20b', class: "calendar-container" }, h("kv-calendar", { key: '87c0a5814c14d756b7ac3610be39e551c9b8789d', mode: this.mode, displayNextMonthArrow: false, displayPreviousMonthArrow: true, selectedDates: selectedDates, hoveredDate: this.hoveredDate, onHoveredDateChange: this.handleHoveredDateChange, disableHoveringStyling: !isHoveringStyleEnabled, initialDate: fromCalendarInitialDate, onChangeMonth: this.handleClickBackMonth, onClickDate: this.onClickDate, minDate: minimumCalendarDate }), h("kv-calendar", { key: '529c70d7002e510e7fe00c7d951fa01e726a9ccc', mode: this.mode, displayNextMonthArrow: true, displayPreviousMonthArrow: false, selectedDates: selectedDates, hoveredDate: this.hoveredDate, onHoveredDateChange: this.handleHoveredDateChange, disableHoveringStyling: !isHoveringStyleEnabled, initialDate: toCalendarInitialDate, onChangeMonth: this.handleClickForwardMonth, onClickDate: this.onClickDate, minDate: minimumCalendarDate })))))); } static get is() { return "kv-absolute-time-picker-dropdown-input"; } static get originalStyleUrls() { return { "$": ["absolute-time-picker-dropdown-input.scss"] }; } static get styleUrls() { return { "$": ["absolute-time-picker-dropdown-input.css"] }; } static get properties() { return { "selectedTime": { "type": "unknown", "attribute": "selected-time", "mutable": false, "complexType": { "original": "SelectedTime | SelectedTimeState", "resolved": "[] | [number, number] | [number]", "references": { "SelectedTime": { "location": "import", "path": "./absolute-time-picker-dropdown-input.types", "id": "src/components/absolute-time-picker-dropdown-input/absolute-time-picker-dropdown-input.types.ts::SelectedTime" }, "SelectedTimeState": { "location": "import", "path": "./absolute-time-picker-dropdown-input.types", "id": "src/components/absolute-time-picker-dropdown-input/absolute-time-picker-dropdown-input.types.ts::SelectedTimeState" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Selected time in timestamp" }, "getter": false, "setter": false }, "timezone": { "type": "unknown", "attribute": "timezone", "mutable": false, "complexType": { "original": "ITimePickerTimezone", "resolved": "{ name: string; offset: number; }", "references": { "ITimePickerTimezone": { "location": "import", "path": "../../types", "id": "src/types.ts::ITimePickerTimezone" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Timezone of the provided timestamp" }, "getter": false, "setter": false, "defaultValue": "getDefaultTimezoneSettings()" }, "mode": { "type": "string", "attribute": "mode", "mutable": false, "complexType": { "original": "EAbsoluteTimePickerMode", "resolved": "EAbsoluteTimePickerMode.Range | EAbsoluteTimePickerMode.Single", "references": { "EAbsoluteTimePickerMode": { "location": "import", "path": "../../types", "id": "src/types.ts::EAbsoluteTimePickerMode" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Mode of the input: single, range" }, "getter": false, "setter": false, "reflect": false, "defaultValue": "EAbsoluteTimePickerMode.Range" }, "isDropdownOpen": { "type": "boolean", "attribute": "is-dropdown-open", "mutable": true, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Determines if the dropdown is open" }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "disabled": { "type": "boolean", "attribute": "disabled", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Defines if the inputs for inserting the dates are disabled." }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" }, "initialDate": { "type": "number", "attribute": "initial-date", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Initial date displayed on the calendars" }, "getter": false, "setter": false, "reflect": false }, "minimumFromInputDate": { "type": "number", "attribute": "minimum-from-input-date", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) calendar from input minimum date" }, "getter": false, "setter": false, "reflect": false }, "minimumToInputDate": { "type": "number", "attribute": "minimum-to-input-date", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) calendar to input minimum date" }, "getter": false, "setter": false, "reflect": false }, "minimumSingleInputDate": { "type": "number", "attribute": "minimum-single-input-date", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) calendar single input minimum date" }, "getter": false, "setter": false, "reflect": false } }; } static get states() { return { "rangeInputValues": {}, "singleTimeInputValue": {}, "displayedMonth": {}, "focusedInput": {}, "hoveredDate": {} }; } static get events() { return [{ "method": "selectedTimeChange", "name": "selectedTimeChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "Selected time change" }, "complexType": { "original": "SelectedTime", "resolved": "[number, number] | [number]", "references": { "SelectedTime": { "location": "import", "path": "./absolute-time-picker-dropdown-input.types", "id": "src/components/absolute-time-picker-dropdown-input/absolute-time-picker-dropdown-input.types.ts::SelectedTime" } } } }, { "method": "dropdownStateChange", "name": "dropdownStateChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "Dropdown open state change" }, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} } }]; } static get watchers() { return [{ "propName": "selectedTime", "methodName": "handleSelectedTimeChange" }]; } }