From b0f166542dae8e74f8837ad8968d8f234b3af630 Mon Sep 17 00:00:00 2001 From: Andrei Vorobev Date: Wed, 27 May 2026 14:40:38 +0300 Subject: [PATCH 1/3] ColorBox: remove m prefix and fix some more type and eslint errors --- packages/devextreme/js/__internal/m_color.ts | 28 ++++++- .../{m_color_box.ts => color_box.ts} | 16 ++-- .../{m_color_view.ts => color_view.ts} | 80 +++++++++++-------- .../ui/html_editor/modules/m_toolbar.ts | 2 +- packages/devextreme/js/ui/color_box.js | 2 +- .../devextreme/js/ui/color_box/color_view.js | 2 +- .../colorBox.markup.tests.js | 2 +- .../colorBox.tests.js | 2 +- .../colorView.markup.tests.js | 2 +- .../colorView.tests.js | 2 +- .../htmlEditorParts/toolbarModule.tests.js | 2 +- 11 files changed, 92 insertions(+), 48 deletions(-) rename packages/devextreme/js/__internal/ui/color_box/{m_color_box.ts => color_box.ts} (97%) rename packages/devextreme/js/__internal/ui/color_box/{m_color_view.ts => color_view.ts} (93%) diff --git a/packages/devextreme/js/__internal/m_color.ts b/packages/devextreme/js/__internal/m_color.ts index 9b9096fb6126..f0e91f5d5129 100644 --- a/packages/devextreme/js/__internal/m_color.ts +++ b/packages/devextreme/js/__internal/m_color.ts @@ -259,6 +259,27 @@ const standardColorTypes = [ // eslint-disable-next-line @typescript-eslint/naming-convention const _round = Math.round; +export interface ColorInstance { + baseColor: string | undefined; + r: number; + g: number; + b: number; + a: number; + hsv: { h: number; s: number; v: number }; + hsl: { h: number; s: number; l: number }; + colorIsInvalid: boolean; + highlight: (step?: number) => string; + darken: (step?: number) => string; + alter: (step: number) => ColorInstance; + blend: (blendColor: ColorInstance | string, opacity: number) => ColorInstance; + toHex: () => string; + getPureColor: () => ColorInstance; + isValidHex: (hex: string) => boolean; + isValidRGB: (r: number, g: number, b: number) => boolean; + isValidAlpha: (a: number) => boolean; + fromHSL: (hsl: { h: number; s: number; l: number }) => ColorInstance; +} + function Color(value?) { this.baseColor = value; let color; @@ -580,4 +601,9 @@ Color.prototype = { }, }; -export default Color; +interface ColorConstructor { + prototype: ColorInstance; + new(value?: string): ColorInstance; +} + +export default Color as unknown as ColorConstructor; diff --git a/packages/devextreme/js/__internal/ui/color_box/m_color_box.ts b/packages/devextreme/js/__internal/ui/color_box/color_box.ts similarity index 97% rename from packages/devextreme/js/__internal/ui/color_box/m_color_box.ts rename to packages/devextreme/js/__internal/ui/color_box/color_box.ts index 08deb3051979..51b5f6cb6571 100644 --- a/packages/devextreme/js/__internal/ui/color_box/m_color_box.ts +++ b/packages/devextreme/js/__internal/ui/color_box/color_box.ts @@ -10,8 +10,8 @@ import type { ValueChangedEvent } from '@ts/ui/editor/editor'; import type { PopupProperties } from '../popup/m_popup'; import type Popup from '../popup/m_popup'; -import type { ColorViewProperties } from './m_color_view'; -import ColorView from './m_color_view'; +import type { ColorViewProperties } from './color_view'; +import ColorView from './color_view'; const COLOR_BOX_CLASS = 'dx-colorbox'; const COLOR_BOX_INPUT_CLASS = `${COLOR_BOX_CLASS}-input`; @@ -281,7 +281,8 @@ class ColorBox extends DropDownEditor { super._cancelButtonHandler(); } - // needed to be typed in widget.ts + // need to be typed in widget.ts + // eslint-disable-next-line @typescript-eslint/no-explicit-any _getKeyboardListeners(): any[] { return super._getKeyboardListeners().concat([this._colorView]); } @@ -303,7 +304,7 @@ class ColorBox extends DropDownEditor { } _renderNoColorIcon(): void { - if (!this._$noColorIcon || !this._$noColorIcon.length) { + if (!this._$noColorIcon?.length) { this._$noColorIcon = $('') .addClass(`${DX_ICON_CLASS} ${DX_ICON_COLOR_DISMISS}`) .appendTo(this._$colorResultPreview); @@ -316,7 +317,7 @@ class ColorBox extends DropDownEditor { this._$colorBoxInputContainer.toggleClass(COLOR_BOX_COLOR_IS_NOT_DEFINED, !hasValue); - if (hasValue) { + if (value !== null && value !== undefined) { this._cleanNoColorIcon(); colorUtils.makeTransparentBackground(this._$colorResultPreview, value); @@ -394,7 +395,6 @@ class ColorBox extends DropDownEditor { return value; } - // eslint-disable-next-line class-methods-use-this _shouldLogFieldTemplateDeprecationWarning(): boolean { return true; } @@ -435,7 +435,9 @@ class ColorBox extends DropDownEditor { case 'applyButtonText': case 'cancelButtonText': super._optionChanged(args); - this._popup && this._addPopupBottomClasses(); + if (this._popup) { + this._addPopupBottomClasses(); + } break; case 'editAlphaChannel': case 'keyStep': diff --git a/packages/devextreme/js/__internal/ui/color_box/m_color_view.ts b/packages/devextreme/js/__internal/ui/color_box/color_view.ts similarity index 93% rename from packages/devextreme/js/__internal/ui/color_box/m_color_view.ts rename to packages/devextreme/js/__internal/ui/color_box/color_view.ts index d716557dd2cc..84ac77dada6e 100644 --- a/packages/devextreme/js/__internal/ui/color_box/m_color_view.ts +++ b/packages/devextreme/js/__internal/ui/color_box/color_view.ts @@ -10,11 +10,11 @@ import { Guid } from '@ts/core/m_guid'; import { extend } from '@ts/core/utils/m_extend'; import { getHeight, getOuterHeight, getWidth } from '@ts/core/utils/m_size'; import type { OptionChanged } from '@ts/core/widget/types'; -import type { SupportedKeys } from '@ts/core/widget/widget'; +import type { SupportedKeyHandler, SupportedKeys } from '@ts/core/widget/widget'; import eventsEngine from '@ts/events/core/m_events_engine'; import { name as clickEventName } from '@ts/events/m_click'; import { isCommandKeyPressed } from '@ts/events/utils/index'; -import Color from '@ts/m_color'; +import Color, { type ColorInstance } from '@ts/m_color'; import Draggable from '@ts/m_draggable'; import type { EditorProperties, ValueChangedEvent } from '@ts/ui/editor/editor'; import Editor from '@ts/ui/editor/editor'; @@ -85,6 +85,23 @@ export interface ColorViewProperties extends EditorProperties { target?: string | Element | dxElementWrapper | null; } +type EditorWithLabelType = new ( + element: dxElementWrapper, + options?: object, +) => { registerKeyHandler: (key: string, handler: SupportedKeyHandler) => void }; + +interface EditorWithLabelOptions { + editorType: EditorWithLabelType; + value: number | string; + onValueChanged: (args: ValueChangedEvent) => void; + labelText: string; + labelAriaText: string; + labelClass: string; + min?: number; + max?: number; + step?: number; +} + class ColorView extends Editor { _$palette!: dxElementWrapper; @@ -100,8 +117,7 @@ class ColorView extends Editor { _updateByDrag?: boolean; - // need typings and correct class in m_color.ts - _currentColor!: any; + _currentColor!: ColorInstance; _isTopColorHue?: boolean; @@ -401,20 +417,16 @@ class ColorView extends Editor { this._renderAlphaChannelElements(); } - _makeTransparentBackground($el: dxElementWrapper, color: any): void { - if (!(color instanceof Color)) { - color = new Color(color); - } + _makeTransparentBackground($el: dxElementWrapper, color: string | ColorInstance): void { + const colorInstance = color instanceof Color ? color : new Color(color); - $el.css('backgroundColor', this._makeRgba(color)); + $el.css('backgroundColor', this._makeRgba(colorInstance)); } - _makeRgba(color: any): string { - if (!(color instanceof Color)) { - color = new Color(color); - } + _makeRgba(color: string | ColorInstance): string { + const colorInstance = color instanceof Color ? color : new Color(color); - return `rgba(${[color.r, color.g, color.b, color.a].join(', ')})`; + return `rgba(${[colorInstance.r, colorInstance.g, colorInstance.b, colorInstance.a].join(', ')})`; } _renderColorPickerContainer(): void { @@ -438,15 +450,12 @@ class ColorView extends Editor { if (delta < 0) { delta = Math.abs(delta); const rows: dxElementWrapper[] = []; - let i; - for (i = 0; i < delta; i++) { + for (let i = 0; i < delta; i += 1) { rows.push($('
').addClass(COLOR_VIEW_ROW_CLASS)); } if (renderedRowsCount) { - for (i = 0; i < rows.length; i++) { - $renderedRows.eq(0).after(rows[i]); - } + rows.forEach((row) => { $renderedRows.eq(0).after(row); }); } else { this._$colorPickerContainer.append(rows); } @@ -539,12 +548,12 @@ class ColorView extends Editor { _calculateColorValue(paletteHandlePosition: PaletteHandlePosition): number { const value = Math.floor(paletteHandlePosition.top + this._paletteHandleHeight / 2); - return 100 - Math.round(value * 100 / this._paletteHeight); + return 100 - Math.round((value * 100) / this._paletteHeight); } _calculateColorSaturation(paletteHandlePosition: PaletteHandlePosition): number { const saturation = Math.floor(paletteHandlePosition.left + this._paletteHandleWidth / 2); - return Math.round(saturation * 100 / this._paletteWidth); + return Math.round((saturation * 100) / this._paletteWidth); } _updateColorFromHsv(hue: number, saturation: number, value: number): void { @@ -603,7 +612,7 @@ class ColorView extends Editor { _placeHueScaleHandle(): void { const hueScaleHeight = this._hueScaleWrapperHeight; const handleHeight = this._hueScaleHandleHeight; - let top = (hueScaleHeight - handleHeight) * (360 - this._currentColor.hsv.h) / 360; + let top = ((hueScaleHeight - handleHeight) * (360 - this._currentColor.hsv.h)) / 360; if (hueScaleHeight < top + handleHeight) { top = hueScaleHeight - handleHeight; @@ -662,7 +671,7 @@ class ColorView extends Editor { this._$currentColor = $('
').addClass([COLOR_VIEW_COLOR_PREVIEW, COLOR_VIEW_COLOR_PREVIEW_COLOR_NEW].join(' ')); this._$baseColor = $('
').addClass([COLOR_VIEW_COLOR_PREVIEW, COLOR_VIEW_COLOR_PREVIEW_COLOR_CURRENT].join(' ')); - this._makeTransparentBackground(this._$baseColor, matchValue); + this._makeTransparentBackground(this._$baseColor, matchValue ?? ''); this._makeTransparentBackground(this._$currentColor, this._currentColor); $colorsPreviewContainerInner.append([this._$baseColor, this._$currentColor]); @@ -718,7 +727,7 @@ class ColorView extends Editor { ]; } - _renderEditorWithLabel(options): dxElementWrapper { + _renderEditorWithLabel(options: EditorWithLabelOptions): dxElementWrapper { const $editor = $('
'); const $label = $('