UNPKG

@kelvininc/ui-components

Version:
581 lines (580 loc) 25.7 kB
import { Host, h } from "@stencil/core"; import { EAbsoluteTimePickerMode } from "../absolute-time-picker/absolute-time-picker.types"; import { buildTimezoneByOffset, getDefaultTimezone, getTimezoneOffset, getTimezonesNames } from "../../utils/date"; import { CALENDAR_MASK, DATETIME_INPUT_MASK } from "../absolute-time-picker/absolute-time-picker.config"; import { buildCustomIntervalTimeRange, buildTooltipText, hasRangeChanged } from "../time-picker/time-picker.helper"; import { isEmpty, isNumber, merge } from "lodash-es"; import { DEFAULT_TIME_RANGE_DROPDOWN_POSITION_OPTIONS, DEFAULT_TIME_RANGE_PICKER_INPUT_CONFIG } from "../time-picker/time-picker.config"; import dayjs from "dayjs"; import { EActionButtonType } from "../action-button/action-button.types"; import { EComponentSize, ETooltipPosition } from "../../types"; import { getSelectedTimestampDates, getFormattedSelectedDates, isAbsoluteTimePickerFilled, getAbsoluteTimePickerError } from "./absolute-time-picker-dropdown.utils"; export class KvAbsoluteTimePickerDropdown { constructor() { /** @inheritdoc */ this.inputConfig = {}; /** @inheritdoc */ this.dropdownPositionOptions = DEFAULT_TIME_RANGE_DROPDOWN_POSITION_OPTIONS; /** @inheritdoc */ this.selectedDates = []; /** @inheritdoc */ this.timezones = buildTimezoneByOffset(getTimezonesNames()); /** @inheritdoc */ this.disabledDates = []; /** @inheritdoc */ this.mode = EAbsoluteTimePickerMode.Single; /** @inheritdoc */ this.tooltipPosition = ETooltipPosition.BottomStart; /** @inheritdoc */ this.headerTitle = ''; /** @inheritdoc */ this.disabled = false; /** @inheritdoc */ this.dropdownOpen = false; // Defines the calendar initial date if needed this.calendarInitialDate = this.initialDate; // Current selected option this.selectedDateState = []; this.getSelectedTimezone = () => { if (!isEmpty(this.timezone)) return this.timezone; const defaultTimezone = getDefaultTimezone(); return { name: defaultTimezone, offset: getTimezoneOffset(defaultTimezone) }; }; this.handleAbsoluteDatesChange = ({ detail }) => { const range = detail.range; const { name: timezoneName } = this.getSelectedTimezone(); this.selectedDateState = getSelectedTimestampDates(range, this.mode, timezoneName); }; this.getAbsoluteRange = () => { const { name: timezoneName } = this.getSelectedTimezone(); return getFormattedSelectedDates(this.selectedDateState, this.mode, timezoneName); }; this.getCalendarLimitDatesFormatted = (date) => { if (!isNumber(date)) return; const selectedTimezone = this.getSelectedTimezone(); return dayjs(date).tz(selectedTimezone.name).format(DATETIME_INPUT_MASK); }; this.onDropdownChange = ({ detail: isDropdownOpen }) => { this.dropdownOpen = isDropdownOpen; this.dropdownStateChange.emit(isDropdownOpen); }; this.getTextFieldTooltip = () => { var _a; if (((_a = this.selectedDates) === null || _a === void 0 ? void 0 : _a.length) > 0) { return buildTooltipText(this.selectedDates, this.getSelectedTimezone(), this.timezones); } }; this.getDropdownInputValue = () => { return buildCustomIntervalTimeRange(this.selectedDates, this.getSelectedTimezone().name); }; this.getInputConfig = () => { const inputValue = this.getDropdownInputValue(); return merge({}, DEFAULT_TIME_RANGE_PICKER_INPUT_CONFIG, this.inputConfig, { value: inputValue, tooltipConfig: { text: this.getTextFieldTooltip(), position: this.tooltipPosition } }); }; this.onClickApply = () => { this.selectedDatesChange.emit(this.selectedDateState); this.dropdownStateChange.emit(false); this.dropdownOpen = false; }; this.onClickCancel = (event) => { this.undoLastChanges(); this.cancelClicked.emit(event); this.dropdownOpen = false; }; this.undoLastChanges = () => { if (!isEmpty(this.selectedDates)) { this.selectedDateState = this.selectedDates; } else { this.selectedDateState = []; } }; } componentWillLoad() { var _a, _b; if (((_a = this.selectedDates) === null || _a === void 0 ? void 0 : _a.length) > 0 && ((_b = this.selectedDateState) === null || _b === void 0 ? void 0 : _b.length) === 0) { this.selectedDateState = this.selectedDates; this.handleSelecteDatesChange(this.selectedDates); } } handleSelecteDatesChange(newDates) { this.selectedDateState = newDates; if (isEmpty(this.initialDate) && (newDates === null || newDates === void 0 ? void 0 : newDates.length) > 0) { const [fromDate] = newDates; this.calendarInitialDate = dayjs(fromDate).format(CALENDAR_MASK); } } render() { const dropdownPositionConfig = this.dropdownPositionOptions; const inputConfig = this.getInputConfig(); const error = getAbsoluteTimePickerError(this.selectedDateState, this.mode, { minDate: this.calendarInputMinDate, maxDate: this.calendarInputMaxDate }); const isFilled = isAbsoluteTimePickerFilled(this.selectedDateState, this.mode); const isDirty = hasRangeChanged(this.selectedDateState, this.selectedDates); const hasError = error !== undefined; const isApplyDisabled = !isFilled || hasError || !isDirty; return (h(Host, { key: 'e8a6c8392f1fd83a285f5464f325d285666566e1' }, h("kv-dropdown", { key: 'f8184559f8ea3e54c3e68a62b75cc674524e96c9', isOpen: this.dropdownOpen, onOpenStateChange: this.onDropdownChange, inputConfig: inputConfig, options: dropdownPositionConfig, disabled: this.disabled }, h("div", { key: '7f9a37b66cdde9c499787fc92e81bba976b1e229', class: "absolute-time-content" }, h("kv-absolute-time-picker", { key: '5f0321217c06709ba47cc1269be3fd0fd73c70f7', mode: this.mode, headerTitle: this.headerTitle, selectedDates: this.getAbsoluteRange(), disabledDates: this.disabledDates, initialDate: this.calendarInitialDate, onSelectedDatesChange: this.handleAbsoluteDatesChange, calendarInputMinDate: this.getCalendarLimitDatesFormatted(this.calendarInputMinDate), calendarInputMaxDate: this.getCalendarLimitDatesFormatted(this.calendarInputMaxDate), error: error }), h("div", { key: '4665e0872f9b6cbd9067f3b45c2253ce10ecc710', class: "footer" }, h("div", { key: '46779a15bdf99ae88ce29a99ad6d45c417342bb5', class: "actions" }, h("kv-action-button-text", { key: '53601132a95621dd5b1deb6f0998aa724dc01621', type: EActionButtonType.Tertiary, size: EComponentSize.Small, text: "Cancel", onClickButton: this.onClickCancel }), h("kv-action-button-text", { key: '36dbacf08df298b9d522ad9d62cb63a4825e1da1', type: EActionButtonType.Primary, size: EComponentSize.Small, text: "Apply", disabled: isApplyDisabled, onClickButton: this.onClickApply }))))))); } static get is() { return "kv-absolute-time-picker-dropdown"; } static get originalStyleUrls() { return { "$": ["absolute-time-picker-dropdown.scss"] }; } static get styleUrls() { return { "$": ["absolute-time-picker-dropdown.css"] }; } static get properties() { return { "inputConfig": { "type": "unknown", "attribute": "input-config", "mutable": false, "complexType": { "original": "Partial<ITextField>", "resolved": "{ type?: EInputFieldType; label?: string; icon?: EIconName; actionIcon?: EIconName; inputName?: string; examples?: string[]; placeholder?: string; maxLength?: number; minLength?: number; max?: string | number; min?: string | number; step?: string | number; size?: EComponentSize; inputDisabled?: boolean; inputRequired?: boolean; loading?: boolean; state?: EValidationState; helpText?: string | string[]; value?: string | number; valuePrefix?: string; badge?: string; inputReadonly?: boolean; forcedFocus?: boolean; tooltipConfig?: Partial<ITooltip>; useInputMask?: boolean; inputMaskRegex?: string; fitContent?: boolean; customStyle?: { [key: string]: string; }; isDirty?: boolean; hideBadge?: boolean; }", "references": { "Partial": { "location": "global", "id": "global::Partial" }, "ITextField": { "location": "import", "path": "../text-field/text-field.types", "id": "src/components/text-field/text-field.types.ts::ITextField" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) dropdown input config" }, "getter": false, "setter": false, "defaultValue": "{}" }, "dropdownPositionOptions": { "type": "unknown", "attribute": "dropdown-position-options", "mutable": false, "complexType": { "original": "Partial<ComputePositionConfig>", "resolved": "{ strategy?: Strategy; placement?: Placement; middleware?: (false | { name: string; options?: any; fn: (state: { x: number; y: number; initialPlacement: Placement; strategy: Strategy; platform: Platform; placement: Placement; middlewareData: MiddlewareData; rects: ElementRects; elements: Elements; }) => Promisable<MiddlewareReturn>; })[]; platform?: Platform; }", "references": { "Partial": { "location": "global", "id": "global::Partial" }, "ComputePositionConfig": { "location": "import", "path": "@floating-ui/dom", "id": "../../node_modules/.pnpm/@floating-ui+dom@1.6.11/node_modules/@floating-ui/dom/dist/floating-ui.dom.d.ts::ComputePositionConfig" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Dropdown positioning config" }, "getter": false, "setter": false, "defaultValue": "DEFAULT_TIME_RANGE_DROPDOWN_POSITION_OPTIONS" }, "selectedDates": { "type": "unknown", "attribute": "selected-dates", "mutable": false, "complexType": { "original": "SelectedTimestamp", "resolved": "[] | [number, number] | [number]", "references": { "SelectedTimestamp": { "location": "import", "path": "../../types", "id": "src/types.ts::SelectedTimestamp" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Selected dates" }, "getter": false, "setter": false, "defaultValue": "[]" }, "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 selected dates" }, "getter": false, "setter": false }, "timezones": { "type": "unknown", "attribute": "timezones", "mutable": false, "complexType": { "original": "ITimezoneOffset[]", "resolved": "ITimezoneOffset[]", "references": { "ITimezoneOffset": { "location": "import", "path": "../../types", "id": "src/types.ts::ITimezoneOffset" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Available Timezones" }, "getter": false, "setter": false, "defaultValue": "buildTimezoneByOffset(getTimezonesNames())" }, "disabledDates": { "type": "unknown", "attribute": "disabled-dates", "mutable": false, "complexType": { "original": "string[]", "resolved": "string[]", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Disabled dates" }, "getter": false, "setter": false, "defaultValue": "[]" }, "initialDate": { "type": "string", "attribute": "initial-date", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Initial Date" }, "getter": false, "setter": false, "reflect": false }, "calendarInputMinDate": { "type": "number", "attribute": "calendar-input-min-date", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) calendar minimum date to be navigated in timestamp" }, "getter": false, "setter": false, "reflect": false }, "calendarInputMaxDate": { "type": "number", "attribute": "calendar-input-max-date", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) calendar maximum date to be navigated in timestamp" }, "getter": false, "setter": false, "reflect": false }, "mode": { "type": "string", "attribute": "mode", "mutable": false, "complexType": { "original": "EAbsoluteTimePickerMode", "resolved": "EAbsoluteTimePickerMode.Range | EAbsoluteTimePickerMode.Single", "references": { "EAbsoluteTimePickerMode": { "location": "import", "path": "../absolute-time-picker/absolute-time-picker.types", "id": "src/components/absolute-time-picker/absolute-time-picker.types.ts::EAbsoluteTimePickerMode" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Defines if the calendar is in single date or range mode" }, "getter": false, "setter": false, "reflect": false, "defaultValue": "EAbsoluteTimePickerMode.Single" }, "tooltipPosition": { "type": "string", "attribute": "tooltip-position", "mutable": false, "complexType": { "original": "ETooltipPosition", "resolved": "ETooltipPosition.Bottom | ETooltipPosition.BottomEnd | ETooltipPosition.BottomStart | ETooltipPosition.Left | ETooltipPosition.LeftEnd | ETooltipPosition.LeftStart | ETooltipPosition.Right | ETooltipPosition.RightEnd | ETooltipPosition.RightStart | ETooltipPosition.Top | ETooltipPosition.TopEnd | ETooltipPosition.TopStart", "references": { "ETooltipPosition": { "location": "import", "path": "../../types", "id": "src/types.ts::ETooltipPosition" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Positioning of the tooltip" }, "getter": false, "setter": false, "reflect": false, "defaultValue": "ETooltipPosition.BottomStart" }, "headerTitle": { "type": "string", "attribute": "header-title", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) Title displayed on top of the component" }, "getter": false, "setter": false, "reflect": false, "defaultValue": "''" }, "disabled": { "type": "boolean", "attribute": "disabled", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) If `true` the dropdown is disabled. Default: `false`." }, "getter": false, "setter": false, "reflect": true, "defaultValue": "false" }, "dropdownOpen": { "type": "boolean", "attribute": "dropdown-open", "mutable": true, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "(optional) If `true`the calendar dropdown is will be open. Default: `false`" }, "getter": false, "setter": false, "reflect": false, "defaultValue": "false" } }; } static get states() { return { "calendarInitialDate": {}, "selectedDateState": {} }; } static get events() { return [{ "method": "selectedDatesChange", "name": "selectedDatesChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "Selected dates change" }, "complexType": { "original": "[number] | [number, number]", "resolved": "[number, number] | [number]", "references": {} } }, { "method": "cancelClicked", "name": "cancelClicked", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [{ "name": "inheritdoc", "text": undefined }], "text": "Cancel button clicked" }, "complexType": { "original": "CustomEvent<MouseEvent>", "resolved": "CustomEvent<MouseEvent>", "references": { "CustomEvent": { "location": "global", "id": "global::CustomEvent" }, "MouseEvent": { "location": "global", "id": "global::MouseEvent" } } } }, { "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": "selectedDates", "methodName": "handleSelecteDatesChange" }]; } }