From a3d038e9ec1ba98fc9bba9cc7b01faf5bc94ce98 Mon Sep 17 00:00:00 2001 From: Andrei Vorobev Date: Fri, 29 May 2026 16:45:07 +0300 Subject: [PATCH 1/6] Autocomplete: fixed eslint, tsexpect errors, warnings --- .../ui/drop_down_editor/m_drop_down_list.ts | 11 +-- .../js/__internal/ui/m_autocomplete.ts | 84 +++++++++++-------- .../js/__internal/ui/m_select_box.ts | 8 +- .../devextreme/js/__internal/ui/m_tag_box.ts | 3 - 4 files changed, 54 insertions(+), 52 deletions(-) diff --git a/packages/devextreme/js/__internal/ui/drop_down_editor/m_drop_down_list.ts b/packages/devextreme/js/__internal/ui/drop_down_editor/m_drop_down_list.ts index 080378951fdf..00a705735d19 100644 --- a/packages/devextreme/js/__internal/ui/drop_down_editor/m_drop_down_list.ts +++ b/packages/devextreme/js/__internal/ui/drop_down_editor/m_drop_down_list.ts @@ -57,10 +57,13 @@ interface DropDownListProperties extends Omit extends DropDownEditor { + declare protected _displayGetter: (item: unknown) => string; // DataExpressionMixin workaround + + declare protected _compileDisplayGetter: () => void; // DataExpressionMixin workaround + _list?: List; _$list?: dxElementWrapper; @@ -418,9 +421,8 @@ class DropDownList< this.option('displayValue', displayValue); } - _displayValue(item: Item): string { - // @ts-expect-error refactor DataExpressionMixin - return this._displayGetter(item) as string; + _displayValue(item): string { + return this._displayGetter(item); } _refreshSelected(): void { @@ -1033,7 +1035,6 @@ class DropDownList< _setSubmitValue(): void { const { value } = this.option(); - // @ts-expect-error refactor DataExpressionMixin const submitValue = this._shouldUseDisplayValue(value) ? this._displayGetter(value) : value; this._getSubmitElement().val(submitValue); diff --git a/packages/devextreme/js/__internal/ui/m_autocomplete.ts b/packages/devextreme/js/__internal/ui/m_autocomplete.ts index 39da053ba0e7..41f7fd9b8f4a 100644 --- a/packages/devextreme/js/__internal/ui/m_autocomplete.ts +++ b/packages/devextreme/js/__internal/ui/m_autocomplete.ts @@ -1,30 +1,38 @@ -import { isCommandKeyPressed } from '@js/common/core/events/utils/index'; -import registerComponent from '@js/core/component_registrator'; +import registerComponent from '@js/core/component_registrator'; // couldn't change import due inconsistent typings for registerComponent +import type { dxElementWrapper } from '@js/core/renderer'; import $ from '@js/core/renderer'; -import { Deferred } from '@js/core/utils/deferred'; -import { extend } from '@js/core/utils/extend'; +import type { DataSourceOptions } from '@js/data/data_source'; +import type { DxEvent, PointerInteractionEvent } from '@js/events/events.types'; import type { Properties } from '@js/ui/autocomplete'; -import { isDefined } from '@ts/core/utils/m_type'; +import type { ItemClickEvent, PageLoadMode } from '@js/ui/list'; +import { Deferred } from '@ts/core/utils/m_deferred'; import type { OptionChanged } from '@ts/core/widget/types'; +import { isCommandKeyPressed } from '@ts/events/utils/index'; import DropDownList from '@ts/ui/drop_down_editor/m_drop_down_list'; +import type { ListBaseProperties } from '@ts/ui/list/list.base'; const AUTOCOMPLETE_CLASS = 'dx-autocomplete'; const AUTOCOMPLETE_POPUP_WRAPPER_CLASS = 'dx-autocomplete-popup-wrapper'; -export interface AutocompleteProperties extends Omit {} +export interface AutocompleteProperties extends Omit< + Properties, 'onItemClick' | 'onSelectionChanged' +> { + +} class Autocomplete extends DropDownList { _supportedKeys(): Record boolean> { - let item = this._list ? this._list.option('focusedElement') : null; + let item: dxElementWrapper | null = null; + if (this._list) { + const { focusedElement } = this._list.option(); + item = focusedElement ? $(focusedElement) : null; + } const parent = super._supportedKeys(); - // @ts-expect-error ts-error - item = item && $(item); return { ...parent, - upArrow(e): boolean { - // @ts-expect-error ts-error - if (parent.upArrow.apply(this, arguments) && !isCommandKeyPressed(e)) { + upArrow: (e): boolean => { + if (parent.upArrow.call(this, e) && !isCommandKeyPressed(e)) { e.preventDefault(); e.stopPropagation(); if (item && !this._calcNextItem(-1)) { @@ -34,9 +42,8 @@ class Autocomplete extends DropDownList { } return true; }, - downArrow(e): boolean { - // @ts-expect-error ts-error - if (parent.downArrow.apply(this, arguments) && !isCommandKeyPressed(e)) { + downArrow: (e): boolean => { + if (parent.downArrow.call(this, e) && !isCommandKeyPressed(e)) { e.preventDefault(); e.stopPropagation(); if (item && !this._calcNextItem(1)) { @@ -46,7 +53,7 @@ class Autocomplete extends DropDownList { } return true; }, - enter(e): boolean { + enter: (e): boolean => { if (!item) { this.close(); } @@ -54,7 +61,7 @@ class Autocomplete extends DropDownList { if (opened) { e.preventDefault(); } - return opened; + return Boolean(opened); }, }; } @@ -78,17 +85,17 @@ class Autocomplete extends DropDownList { _getAriaAutocomplete(): string { const { disabled, readOnly } = this.option(); - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const isInputEditable = !(readOnly || disabled); + const isInputEditable = !(readOnly ?? disabled); return isInputEditable ? 'list' : 'none'; } - _displayGetterExpr() { - return this.option('valueExpr'); + _displayGetterExpr(): undefined | string | ((item: unknown) => string | number | boolean) { + const { valueExpr } = this.option(); + return valueExpr; } - _closeOutsideDropDownHandler({ target }): boolean { + _closeOutsideDropDownHandler({ target }: DxEvent): boolean { return !$(target).closest(this.$element()).length; } @@ -103,18 +110,18 @@ class Autocomplete extends DropDownList { return `${super._popupWrapperClass()} ${AUTOCOMPLETE_POPUP_WRAPPER_CLASS}`; } - _listConfig() { - return extend(super._listConfig(), { - pageLoadMode: 'none', - onSelectionChanged: (e) => { + _listConfig(): ListBaseProperties { + return { + ...super._listConfig(), + pageLoadMode: 'none' as PageLoadMode, + onSelectionChanged: (e): void => { this._setSelectedItem(e.addedItems[0]); }, - }); + }; } - _listItemClickHandler(e) { + _listItemClickHandler(e: ItemClickEvent): void { this._saveValueChangeEvent(e.event); - // @ts-expect-error ts-error const value = this._displayGetter(e.itemData); this.option('value', value); this.close(); @@ -129,20 +136,25 @@ class Autocomplete extends DropDownList { super._setListDataSource(); } - _refreshSelected(): void {} + // eslint-disable-next-line class-methods-use-this + _refreshSelected(): void { + // Autocomplete has no persistent selection state — suppress parent behavior + // _refreshSelected is called in parent, so we need to override here + // hence we don't need this functionality in Autocomplete + } _searchCanceled(): void { super._searchCanceled(); this.close(); } - _loadItem(value, cache) { - const selectedItem = this._getItemFromPlain(value, cache); + _loadItem(value: unknown, cache: Record): ReturnType { + const selectedItem = this._getItemFromPlain(value, cache) as unknown; return Deferred().resolve(selectedItem).promise(); } - _dataSourceOptions() { + _dataSourceOptions(): DataSourceOptions { const { maxItemCount } = this.option(); return { paginate: true, @@ -171,7 +183,7 @@ class Autocomplete extends DropDownList { return 'input keyup'; } - _valueChangeEventHandler(e): void { + _valueChangeEventHandler(e: KeyboardEvent): void { const value = this._input().val() || null; return super._valueChangeEventHandler(e, value); } @@ -184,11 +196,9 @@ class Autocomplete extends DropDownList { this._setDefaultAria(); break; case 'maxItemCount': - // @ts-expect-error ts-error - this._searchDataSource(); + this._searchDataSource(this._searchValue()); break; case 'valueExpr': - // @ts-expect-error ts-error this._compileDisplayGetter(); this._setListOption('displayExpr', this._displayGetterExpr()); super._optionChanged(args); diff --git a/packages/devextreme/js/__internal/ui/m_select_box.ts b/packages/devextreme/js/__internal/ui/m_select_box.ts index d3c35d847391..2e054af22306 100644 --- a/packages/devextreme/js/__internal/ui/m_select_box.ts +++ b/packages/devextreme/js/__internal/ui/m_select_box.ts @@ -449,7 +449,6 @@ class SelectBox< const fieldTemplate = this._getTemplate(fieldTemplateOption); if (!(fieldTemplate && fieldTemplateOption)) { - // @ts-expect-error ts-error const text = this._displayGetter(item); this.option('text', text); @@ -559,7 +558,6 @@ class SelectBox< return false; } - // @ts-expect-error ts-error const value = this._displayGetter(initialSelectedItem); const displayValue = value ? String(value) : ''; const inputText = this._searchValue(); @@ -693,7 +691,6 @@ class SelectBox< _clearTextValue(): void { const selectedItem = this.option('selectedItem'); - // @ts-expect-error ts-error const selectedItemText = this._displayGetter(selectedItem); const shouldRestoreValue = selectedItem && selectedItemText !== ''; @@ -815,10 +812,9 @@ class SelectBox< return this._loadItemDeferred; } - _isCustomItemSelected() { + _isCustomItemSelected(): boolean { const selectedItem = this.option('selectedItem'); const searchValue = this._searchValue(); - // @ts-expect-error ts-error const selectedItemText = this._displayGetter(selectedItem); return !selectedItemText || searchValue !== selectedItemText.toString(); @@ -881,7 +877,6 @@ class SelectBox< this._cancelSearchIfNeed(); // @ts-expect-error ts-error this._setValue(this._valueGetter(item)); - // @ts-expect-error ts-error this._renderDisplayText(this._displayGetter(item)); this._isValueChanging = false; } @@ -960,7 +955,6 @@ class SelectBox< } const inputElement = $input.get(0) as HTMLInputElement; - // @ts-expect-error ts-error const displayValue = this._displayGetter(item).toString(); inputElement.value = displayValue; this._caret({ start: valueLength, end: displayValue.length }); diff --git a/packages/devextreme/js/__internal/ui/m_tag_box.ts b/packages/devextreme/js/__internal/ui/m_tag_box.ts index ce929c7f33fb..7b4708058658 100644 --- a/packages/devextreme/js/__internal/ui/m_tag_box.ts +++ b/packages/devextreme/js/__internal/ui/m_tag_box.ts @@ -439,7 +439,6 @@ class TagBox< $container.append($tagContent); }, ['text'], this.option('integrationOptions.watchMethod'), { - // @ts-expect-error ts-error text: this._displayGetter, }), }); @@ -488,7 +487,6 @@ class TagBox< $options.push( $('