@kelvininc/ui-components
Version:
Kelvin UI Components
498 lines (497 loc) • 25.5 kB
JavaScript
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"
}];
}
}