Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions packages/devextreme/js/__internal/core/widget/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,7 @@ class Widget<
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
keyboardListeners.forEach((listener) => listener?._keyboardHandler(options));

// eslint-disable-next-line @typescript-eslint/no-unused-expressions
onKeyboardHandled && onKeyboardHandled(options);
onKeyboardHandled?.(options);

return true;
}
Expand Down Expand Up @@ -570,13 +569,12 @@ class Widget<
this.$element().toggleClass('dx-state-independent', ignoreParentReadOnly);
}

_setWidgetOption(widgetName: string, args: Record<string, unknown>): void {
_setWidgetOption(widgetName: string, args: [string, unknown?] | Record<string, unknown>): void {
if (!this[widgetName]) {
return;
}

if (isPlainObject(args[0])) {
// @ts-expect-error
each(args[0], (option, value) => this._setWidgetOption(widgetName, [option, value]));

return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { normalizeDataSourceOptions } from '../../../common/data/data_source/uti
import { extend } from '../../../core/utils/extend';
import { isDefined } from '../../../core/utils/type';

interface DataSourceType {
export interface DataSourceType {
_userData: unknown;
_pageSize: number;
dispose: () => void;
Expand Down Expand Up @@ -47,7 +47,6 @@ interface DataControllerOptions extends Record<string, unknown> {
class DataController {
private _isSharedDataSource = false;

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
private _dataSource: DataSourceType;

Expand Down Expand Up @@ -75,7 +74,6 @@ class DataController {
}

_updateDataSourceByItems(items: unknown[]): void {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
this._dataSource = new DataSource({
store: new ArrayStore({
key: this.key(),
Expand All @@ -93,7 +91,6 @@ class DataController {
this._dataSource.dispose();
}

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
delete this._dataSource;
}
Expand Down Expand Up @@ -126,9 +123,8 @@ class DataController {
}

loadNextPage(): Promise<unknown> {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands

this.pageIndex(1 + this.pageIndex());

return this.load();
Expand Down Expand Up @@ -189,7 +185,7 @@ class DataController {
}
}

updateDataSource(items: unknown[] | DataSourceType, key?: string): void {
updateDataSource(items?: unknown[] | DataSourceType, key?: string): void {
const dataSourceOptions = items ?? this.items();

if (key) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -913,9 +913,9 @@ class DropDownEditor<
showCloseButton: false,
dragEnabled: false,
toolbarItems: this._getPopupToolbarItems(),
// @ts-expect-error Should be updated on PopupProperties level
onPositioned: this._popupPositionedHandler.bind(this),
fullScreen: false,
// @ts-expect-error should be added on Popup level
contentTemplate: null,
_hideOnParentScrollTarget: this.$element(),
_wrapperClassExternal: DROP_DOWN_EDITOR_OVERLAY,
Expand Down Expand Up @@ -1049,7 +1049,6 @@ class DropDownEditor<
}

_setPopupOption(...args: [string, unknown?]): void {
// @ts-expect-error Should be fixed on Widget level
this._setWidgetOption('_popup', args);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,13 @@ interface DropDownListProperties extends Omit<dxDropDownListOptions<DropDownList
displayCustomValue?: boolean;
items?: Item[];
}

class DropDownList<
TProperties extends DropDownListProperties = DropDownListProperties,
> extends DropDownEditor<TProperties> {
declare _displayGetter: (item: unknown) => string; // DataExpressionMixin workaround

declare _compileDisplayGetter: () => void; // DataExpressionMixin workaround

_list?: List;

_$list?: dxElementWrapper;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -703,7 +705,6 @@ class DropDownList<
): void;
_setListOption(optionName: string, value?: unknown): void;
_setListOption(...args: [string, unknown?]): void {
// @ts-expect-error fix on Widget level
this._setWidgetOption('_list', args);
}

Expand Down Expand Up @@ -1033,7 +1034,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);
Expand Down
83 changes: 47 additions & 36 deletions packages/devextreme/js/__internal/ui/m_autocomplete.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
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 type { ItemClickEvent, PageLoadMode } from '@js/ui/list';
import { Deferred } from '@ts/core/utils/m_deferred';
import { isDefined } from '@ts/core/utils/m_type';
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<Properties, 'onItemClick' | 'onSelectionChanged'> {}
export interface AutocompleteProperties extends Omit<
Properties, 'onItemClick' | 'onSelectionChanged'
> {

}

class Autocomplete extends DropDownList<AutocompleteProperties> {
_supportedKeys(): Record<string, (e: KeyboardEvent) => 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)) {
Expand All @@ -34,9 +43,8 @@ class Autocomplete extends DropDownList<AutocompleteProperties> {
}
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)) {
Expand All @@ -46,15 +54,15 @@ class Autocomplete extends DropDownList<AutocompleteProperties> {
}
return true;
},
enter(e): boolean {
enter: (e): boolean => {
if (!item) {
this.close();
}
const { opened } = this.option();
if (opened) {
e.preventDefault();
}
return opened;
return Boolean(opened);
},
};
}
Expand All @@ -78,17 +86,17 @@ class Autocomplete extends DropDownList<AutocompleteProperties> {
_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<PointerInteractionEvent>): boolean {
return !$(target).closest(this.$element()).length;
}

Expand All @@ -103,18 +111,18 @@ class Autocomplete extends DropDownList<AutocompleteProperties> {
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();
Expand All @@ -129,20 +137,25 @@ class Autocomplete extends DropDownList<AutocompleteProperties> {
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<string, unknown>): ReturnType<typeof Deferred> {
const selectedItem = this._getItemFromPlain(value, cache) as unknown;

return Deferred().resolve(selectedItem).promise();
}

_dataSourceOptions() {
_dataSourceOptions(): DataSourceOptions {
const { maxItemCount } = this.option();
return {
paginate: true,
Expand Down Expand Up @@ -171,7 +184,7 @@ class Autocomplete extends DropDownList<AutocompleteProperties> {
return 'input keyup';
}

_valueChangeEventHandler(e): void {
_valueChangeEventHandler(e: KeyboardEvent): void {
const value = this._input().val() || null;
return super._valueChangeEventHandler(e, value);
}
Expand All @@ -184,11 +197,9 @@ class Autocomplete extends DropDownList<AutocompleteProperties> {
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);
Expand Down
Loading
Loading