From df229e2ff21fafebbbc609dfa01ace6469c95386 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 11:09:19 +0100 Subject: [PATCH 01/18] refactor: add types to m_calendar --- .../__internal/scheduler/header/m_calendar.ts | 95 +++++++++++-------- 1 file changed, 55 insertions(+), 40 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts index eaf76198bbe8..fb334443e19c 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts @@ -1,44 +1,52 @@ import registerComponent from '@js/core/component_registrator'; import devices from '@js/core/devices'; +import type { dxElementWrapper } from '@js/core/renderer'; import $ from '@js/core/renderer'; -import Calendar from '@js/ui/calendar'; +import type { DateLike } from '@js/ui/calendar'; import Popover from '@js/ui/popover/ui.popover'; import Popup from '@js/ui/popup/ui.popup'; -import type { dxSchedulerOptions } from '@js/ui/scheduler'; -import Scrollable from '@js/ui/scroll_view/ui.scrollable'; -import Widget from '@js/ui/widget/ui.widget'; +import type { Properties as SchedulerProperties } from '@js/ui/scheduler'; +import Widget from '@ts/core/widget/widget'; +import type { KeyboardKeyDownEvent } from '@ts/events/core/m_keyboard_processor'; +import type { CalendarProperties } from '@ts/ui/calendar/calendar'; +import Calendar from '@ts/ui/calendar/calendar'; +import Scrollable from '@ts/ui/scroll_view/scrollable'; const CALENDAR_CLASS = 'dx-scheduler-navigator-calendar'; const CALENDAR_POPOVER_CLASS = 'dx-scheduler-navigator-calendar-popover'; -export default class SchedulerCalendar extends Widget { - _overlay: any; +/** + * Calendar component that is displayed when clicking on the date navigator in the scheduler header. + * It shows a popup/popover with a calendar widget for date selection. + */ +export default class SchedulerCalendar extends Widget { + _overlay: Popup | Popover | undefined; - _calendar: any; + _calendar: Calendar | undefined; - show(target) { - if (!this._isMobileLayout()) { - this._overlay.option('target', target); + async show(target: HTMLElement): Promise { + if (!SchedulerCalendar._isMobileLayout()) { + this._overlay?.option('target', target); } - this._overlay.show(); + + await this._overlay?.show(); } - hide() { - this._overlay.hide(); + async hide(): Promise { + await this._overlay?.hide(); } - _keyboardHandler(opts): void { + _keyboardHandler(opts: KeyboardKeyDownEvent): boolean { this._calendar?._keyboardHandler(opts); + return true; } _init(): void { - // @ts-expect-error super._init(); this.$element(); } _render(): void { - // @ts-expect-error super._render(); this._renderOverlay(); } @@ -46,17 +54,16 @@ export default class SchedulerCalendar extends Widget { _renderOverlay(): void { this.$element().addClass(CALENDAR_POPOVER_CLASS); - const isMobileLayout = this._isMobileLayout(); - - const overlayType = isMobileLayout ? Popup : Popover; + const isMobileLayout = SchedulerCalendar._isMobileLayout(); - // @ts-expect-error - this._overlay = this._createComponent(this.$element(), overlayType, { + const overlayConfig = { contentTemplate: () => this._createOverlayContent(), - onShown: () => this._calendar.focus(), + onShown: () => { + this._calendar?.focus(); + }, defaultOptionsRules: [ { - device: () => isMobileLayout, + device: (): boolean => isMobileLayout, options: { fullScreen: true, showCloseButton: false, @@ -67,15 +74,20 @@ export default class SchedulerCalendar extends Widget { }, }, ], - }); + } as const; + + if (isMobileLayout) { + this._overlay = this._createComponent(this.$element(), Popup, overlayConfig); + } else { + this._overlay = this._createComponent(this.$element(), Popover, overlayConfig); + } } - _createOverlayContent() { + _createOverlayContent(): dxElementWrapper { const result = $('
').addClass(CALENDAR_CLASS); - // @ts-expect-error this._calendar = this._createComponent(result, Calendar, this._getCalendarOptions()); - if (this._isMobileLayout()) { + if (SchedulerCalendar._isMobileLayout()) { const scrollable = this._createScrollable(result); return scrollable.$element(); } @@ -83,8 +95,7 @@ export default class SchedulerCalendar extends Widget { return result; } - _createScrollable(content) { - // @ts-expect-error + _createScrollable(content: dxElementWrapper): Scrollable { const result = this._createComponent('
', Scrollable, { height: 'auto', direction: 'both', @@ -94,7 +105,9 @@ export default class SchedulerCalendar extends Widget { return result; } - _optionChanged({ name, value }) { + _optionChanged( + { name, value } : { name: string; value: DateLike | DateLike[] }, + ): void { switch (name) { case 'value': this._calendar?.option('value', value); @@ -104,23 +117,25 @@ export default class SchedulerCalendar extends Widget { } } - _getCalendarOptions() { + _getCalendarOptions(): CalendarProperties { + const schedulerOptions = this.option(); return { - value: this.option('value'), - min: this.option('min'), - max: this.option('max'), - firstDayOfWeek: this.option('firstDayOfWeek'), - focusStateEnabled: this.option('focusStateEnabled'), - onValueChanged: this.option('onValueChanged'), + value: schedulerOptions.currentDate, + min: schedulerOptions.min, + max: schedulerOptions.max, + firstDayOfWeek: schedulerOptions.firstDayOfWeek, + focusStateEnabled: schedulerOptions.focusStateEnabled, + tabIndex: schedulerOptions.tabIndex, + // @ts-expect-error onCurrentDateChange exists in HeaderOptions but not in Scheduler types + onValueChanged: schedulerOptions.onCurrentDateChange, + // @ts-expect-error skipFocusCheck is an internal Calendar property skipFocusCheck: true, - tabIndex: this.option('tabIndex'), }; } - _isMobileLayout() { + static _isMobileLayout(): boolean { return !devices.current().generic; } } -// @ts-expect-error registerComponent('dxSchedulerCalendarPopup', SchedulerCalendar); From bcc557077fba72521e0b18b3dc770442c6213c3d Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 13:05:17 +0100 Subject: [PATCH 02/18] refactor: add types to m_header --- .../__internal/scheduler/header/m_calendar.ts | 6 +- .../__internal/scheduler/header/m_header.ts | 172 +++++++++--------- .../scheduler/header/m_view_switcher.ts | 27 ++- .../js/__internal/scheduler/header/today.ts | 3 +- .../js/__internal/scheduler/header/types.ts | 16 +- .../js/__internal/scheduler/m_scheduler.ts | 8 +- 6 files changed, 134 insertions(+), 98 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts index fb334443e19c..3ef28b6776ed 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts @@ -12,6 +12,8 @@ import type { CalendarProperties } from '@ts/ui/calendar/calendar'; import Calendar from '@ts/ui/calendar/calendar'; import Scrollable from '@ts/ui/scroll_view/scrollable'; +import type { SchedulerCalendarProperties } from './types'; + const CALENDAR_CLASS = 'dx-scheduler-navigator-calendar'; const CALENDAR_POPOVER_CLASS = 'dx-scheduler-navigator-calendar-popover'; @@ -19,7 +21,9 @@ const CALENDAR_POPOVER_CLASS = 'dx-scheduler-navigator-calendar-popover'; * Calendar component that is displayed when clicking on the date navigator in the scheduler header. * It shows a popup/popover with a calendar widget for date selection. */ -export default class SchedulerCalendar extends Widget { +export default class SchedulerCalendar extends Widget< +SchedulerProperties & SchedulerCalendarProperties +> { _overlay: Popup | Popover | undefined; _calendar: Calendar | undefined; diff --git a/packages/devextreme/js/__internal/scheduler/header/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/m_header.ts index 049eb0e857f2..c08ebe6a9763 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_header.ts @@ -1,4 +1,3 @@ -import '@js/ui/button_group'; import '@js/ui/drop_down_button'; import registerComponent from '@js/core/component_registrator'; @@ -8,9 +7,12 @@ import $ from '@js/core/renderer'; import { getPathParts } from '@js/core/utils/data'; import dateUtils from '@js/core/utils/date'; import { extend } from '@js/core/utils/extend'; +import type { ItemClickEvent } from '@js/ui/button_group'; +import type { DateNavigatorTextInfo, ToolbarItem } from '@js/ui/scheduler'; import Toolbar from '@js/ui/toolbar'; -import Widget from '@js/ui/widget/ui.widget'; -import type { NormalizedView } from '@ts/scheduler/utils/options/types'; +import type { OptionChanged } from '@ts/core/widget/types'; +import Widget from '@ts/core/widget/widget'; +import type { NormalizedView, SafeSchedulerOptions } from '@ts/scheduler/utils/options/types'; import type { Direction } from './constants'; import SchedulerCalendar from './m_calendar'; @@ -28,7 +30,9 @@ import { getTabViewSwitcher, } from './m_view_switcher'; import { getTodayButtonOptions } from './today'; -import type { HeaderOptions, IntervalOptions } from './types'; +import type { + EventMapHandler, HeaderOptions, IntervalOptions, SchedulerCalendarProperties, +} from './types'; const CLASSES = { component: 'dx-scheduler-header', @@ -41,20 +45,20 @@ const ITEM_NAMES = { }; export class SchedulerHeader extends Widget { - eventMap: any; + eventMap!: Map; _toolbar!: Toolbar; - _calendar: any; + _calendar: SchedulerCalendar | undefined; - get captionText() { + get captionText(): string { return this._getCaption().text; } getIntervalOptions(date: Date): IntervalOptions { - const currentView = this.option('currentView'); + const headerOptions = this.option(); + const { currentView, firstDayOfWeek } = headerOptions; const step = getStep(currentView.type); - const firstDayOfWeek = this.option('firstDayOfWeek'); return { date, @@ -65,44 +69,43 @@ export class SchedulerHeader extends Widget { }; } - _getDefaultOptions() { - // @ts-expect-error + _getDefaultOptions(): HeaderOptions & { _useShortDateFormat: boolean } { return extend(super._getDefaultOptions(), { _useShortDateFormat: !devices.real().generic || devices.isSimulator(), - }); + }) as HeaderOptions & { _useShortDateFormat: boolean }; } - _createEventMap() { - this.eventMap = new Map( - [ - ['currentView', []], - ['views', []], - ['currentDate', [this._getCalendarOptionUpdater('value')]], - ['min', [this._getCalendarOptionUpdater('min')]], - ['max', [this._getCalendarOptionUpdater('max')]], - ['tabIndex', [this.repaint.bind(this)]], - ['focusStateEnabled', [this.repaint.bind(this)]], - ['useDropDownViewSwitcher', [this.repaint.bind(this)]], - ['indicatorTime', []], - ], - ); + _createEventMap(): void { + this.eventMap = new Map([ + ['currentView', []], + ['views', []], + ['currentDate', [this._getCalendarOptionUpdater('value')]], + ['min', [this._getCalendarOptionUpdater('min')]], + ['max', [this._getCalendarOptionUpdater('max')]], + ['tabIndex', [this.repaint.bind(this)]], + ['focusStateEnabled', [this.repaint.bind(this)]], + ['useDropDownViewSwitcher', [this.repaint.bind(this)]], + ['indicatorTime', []], + ] as unknown as [string, EventMapHandler[]][]); } - _addEvent(name, event) { + _addEvent(name: string, event: EventMapHandler): void { if (!this.eventMap.has(name)) { this.eventMap.set(name, []); } const events = this.eventMap.get(name); - this.eventMap.set(name, [...events, event]); + if (events) { + this.eventMap.set(name, [...events, event]); + } } - _optionChanged(args) { + _optionChanged(args: OptionChanged): void { const { name, value } = args; if (this.eventMap.has(name)) { const events = this.eventMap.get(name); - events.forEach((event) => { + events?.forEach((event) => { event(value); }); } @@ -121,30 +124,25 @@ export class SchedulerHeader extends Widget { case fullName === 'toolbar.items': this._toolbar.option( 'items', - (value as []).map((item) => this._parseItem(item)), + (value as []).map((item: ToolbarItem) => this._parseItem(item)), ); break; case parts[1] === 'items' && parts.length === 3: - // `toolbar.items[i]` case - this._toolbar.option(optionName, this._parseItem(value)); + this._toolbar.option(optionName, this._parseItem(value as ToolbarItem)); break; default: - // `toolbar.prop` case - // `toolbar.items[i].prop` case this._toolbar.option(optionName, value); } } - _init() { - // @ts-expect-error + _init(): void { super._init(); this._createEventMap(); this.$element().addClass(CLASSES.component); } - _render() { - // @ts-expect-error + _render(): void { super._render(); this._createEventMap(); @@ -152,20 +150,20 @@ export class SchedulerHeader extends Widget { this._toggleVisibility(); } - _renderToolbar() { + _renderToolbar(): void { const config = this._createToolbarConfig(); const toolbarElement = $('
'); toolbarElement.appendTo(this.$element()); - // @ts-expect-error this._toolbar = this._createComponent(toolbarElement, Toolbar, config); } _toggleVisibility(): void { - const toolbarOptions = this.option('toolbar') as any; + const headerOptions = this.option(); + const toolbarOptions = headerOptions.toolbar; const isHeaderShown = toolbarOptions.visible - || (toolbarOptions.visible === undefined && toolbarOptions.items.length); + ?? (toolbarOptions.visible === undefined && toolbarOptions.items.length); if (isHeaderShown) { this.$element().removeClass(CLASSES.invisible); @@ -174,8 +172,9 @@ export class SchedulerHeader extends Widget { } } - _createToolbarConfig() { - const options = this.option('toolbar'); + _createToolbarConfig(): SafeSchedulerOptions['toolbar'] { + const headerOptions = this.option(); + const options = headerOptions.toolbar; const parsedItems = options.items.map((element) => this._parseItem(element)); return { @@ -184,7 +183,7 @@ export class SchedulerHeader extends Widget { }; } - _parseItem(item) { + _parseItem(item: ToolbarItem | string): ToolbarItem { const itemName = typeof item === 'string' ? item : item.name; const itemOptions = typeof item === 'string' ? {} : item; @@ -205,74 +204,81 @@ export class SchedulerHeader extends Widget { } } - return extend(true, {}, item); + return extend(true, {}, item) as ToolbarItem; } - _callEvent(event, arg) { + _callEvent(event: string, arg: unknown): void { if (this.eventMap.has(event)) { const events = this.eventMap.get(event); - events.forEach((event) => event(arg)); + if (events) { + events.forEach((EventMapHandler) => EventMapHandler(arg)); + } } } - _updateCurrentView(view: Required) { - this.option('onCurrentViewChange')(view.name); + _updateCurrentView(view: Required): void { + const headerOptions = this.option(); + headerOptions.onCurrentViewChange(view.name); } - _updateCalendarValueAndCurrentDate(date) { + _updateCalendarValueAndCurrentDate(date: Date): void { this._updateCurrentDate(date); - this._calendar.option('value', date); + this._calendar?.option('value', date); } - _updateCurrentDate(date) { - this.option('onCurrentDateChange')(date); + _updateCurrentDate(date: Date): void { + const headerOptions = this.option(); + headerOptions.onCurrentDateChange(date); this._callEvent('currentDate', date); } - _renderCalendar() { - // @ts-expect-error + _renderCalendar(): void { + const headerOptions = this.option(); this._calendar = this._createComponent('
', SchedulerCalendar, { - value: this.option('currentDate'), - min: this.option('min'), - max: this.option('max'), - firstDayOfWeek: this.option('firstDayOfWeek'), - focusStateEnabled: this.option('focusStateEnabled'), - tabIndex: this.option('tabIndex'), - onValueChanged: (e) => { + value: headerOptions.currentDate, + min: headerOptions.min, + max: headerOptions.max, + firstDayOfWeek: headerOptions.firstDayOfWeek, + focusStateEnabled: headerOptions.focusStateEnabled, + tabIndex: headerOptions.tabIndex, + onValueChanged: async (e) => { this._updateCurrentDate(e.value); - this._calendar.hide(); + await this._calendar?.hide(); }, }); this._calendar.$element().appendTo(this.$element()); } - _getCalendarOptionUpdater(name) { - return (value) => { + _getCalendarOptionUpdater(name: keyof SchedulerCalendarProperties) { + return (value: SchedulerCalendarProperties[typeof name]): void => { if (this._calendar) { this._calendar.option(name, value); } }; } - _getNextDate(direction: Direction, initialDate?: Date) { - const date = initialDate ?? this.option('currentDate'); + _getNextDate(direction: Direction, initialDate?: Date): Date { + const headerOptions = this.option(); + const date = initialDate ?? headerOptions.currentDate; const options = this.getIntervalOptions(date); return getNextIntervalDate(options, direction); } - _getDisplayedDate() { - const startViewDate = new Date(this.option('startViewDate')); - const isMonth = this.option('currentView')?.type === 'month'; + _getDisplayedDate(): Date { + const headerOptions = this.option(); + const startViewDate = new Date(headerOptions.startViewDate); + const isMonth = headerOptions.currentView.type === 'month'; return isMonth ? nextWeek(startViewDate) : startViewDate; } - _getCaptionOptions() { - let date = this.option('currentDate'); + _getCaptionOptions(): IntervalOptions { + const headerOptions = this.option(); + let date = headerOptions.currentDate; - if (this.option('startViewDate')) { + if (headerOptions.startViewDate) { date = this._getDisplayedDate(); } @@ -281,28 +287,28 @@ export class SchedulerHeader extends Widget { return this.getIntervalOptions(date); } - _getCaption() { + _getCaption(): DateNavigatorTextInfo { + const headerOptions = this.option(); const options = this._getCaptionOptions(); - const customizationFunction = this.option('customizeDateNavigatorText'); + const customizationFunction = headerOptions.customizeDateNavigatorText; const useShortDateFormat = this.option('_useShortDateFormat'); return getCaption(options, Boolean(useShortDateFormat), customizationFunction); } - _updateDateByDirection(direction: Direction) { + _updateDateByDirection(direction: Direction): void { const date = this._getNextDate(direction); this._updateCalendarValueAndCurrentDate(date); } - _showCalendar(e) { - this._calendar.show(e.element); + async _showCalendar(e: ItemClickEvent): Promise { + await this._calendar?.show(e.element); } - _hideCalendar() { - this._calendar.hide(); + async _hideCalendar(): Promise { + await this._calendar?.hide(); } } -// @ts-expect-error registerComponent('dxSchedulerHeader', SchedulerHeader); diff --git a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts index 822499f11681..6b29785c04f4 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts @@ -14,9 +14,14 @@ const ClASS = { dropDownButtonContent: 'dx-scheduler-view-switcher-dropdown-button-content', }; -const getViewsAndSelectedView = (header: SchedulerHeader) => { - const views = formatViews(header.option('views')); - const selectedView = getViewName(header.option('currentView')); +const getViewsAndSelectedView = (header: SchedulerHeader): +{ + selectedView: string | undefined; + views: NormalizedView[]; +} => { + const headerOptions = header.option(); + const views = formatViews(headerOptions.views); + const selectedView = getViewName(headerOptions.currentView); const isSelectedViewInViews = views.some((view) => view.name === selectedView); return { @@ -27,7 +32,10 @@ const getViewsAndSelectedView = (header: SchedulerHeader) => { const isViewSwitcherVisible = (views: NormalizedView[]): boolean => views.length > 1; -export const getTabViewSwitcher = (header: SchedulerHeader, item): ToolbarItem => { +export const getTabViewSwitcher = ( + header: SchedulerHeader, + item: ToolbarItem, +): ToolbarItem => { const { selectedView, views } = getViewsAndSelectedView(header); const isVisible = isViewSwitcherVisible(views); @@ -53,7 +61,7 @@ export const getTabViewSwitcher = (header: SchedulerHeader, item): ToolbarItem = const viewSwitcher = e.component; header._addEvent('currentView', (view) => { - viewSwitcher.option('selectedItemKeys', [getViewName(view)]); + viewSwitcher.option('selectedItemKeys', [getViewName(view as NormalizedView)]); }); }, }, @@ -61,7 +69,10 @@ export const getTabViewSwitcher = (header: SchedulerHeader, item): ToolbarItem = } as ToolbarItem; }; -export const getDropDownViewSwitcher = (header: SchedulerHeader, item): ToolbarItem => { +export const getDropDownViewSwitcher = ( + header: SchedulerHeader, + item: ToolbarItem, +): ToolbarItem => { const { selectedView, views } = getViewsAndSelectedView(header); const isVisible = isViewSwitcherVisible(views); @@ -88,8 +99,8 @@ export const getDropDownViewSwitcher = (header: SchedulerHeader, item): ToolbarI onContentReady: (e) => { const viewSwitcher = e.component; - header._addEvent('currentView', (view: NormalizedView) => { - viewSwitcher.option('selectedItemKey', getViewName(view)); + header._addEvent('currentView', (view) => { + viewSwitcher.option('selectedItemKey', getViewName(view as NormalizedView)); }); }, dropDownOptions: { diff --git a/packages/devextreme/js/__internal/scheduler/header/today.ts b/packages/devextreme/js/__internal/scheduler/header/today.ts index b4b94339aa75..58bc7581171d 100644 --- a/packages/devextreme/js/__internal/scheduler/header/today.ts +++ b/packages/devextreme/js/__internal/scheduler/header/today.ts @@ -18,7 +18,8 @@ export const getTodayButtonOptions = ( stylingMode: 'outlined', type: 'normal', onClick() { - header._updateCurrentDate(header.option('indicatorTime') ?? new Date()); + const headerOptions = header.option(); + header._updateCurrentDate(headerOptions.indicatorTime ?? new Date()); }, }, }, item) as ToolbarItem; diff --git a/packages/devextreme/js/__internal/scheduler/header/types.ts b/packages/devextreme/js/__internal/scheduler/header/types.ts index 98c2ca07eab7..17bcb9bae47b 100644 --- a/packages/devextreme/js/__internal/scheduler/header/types.ts +++ b/packages/devextreme/js/__internal/scheduler/header/types.ts @@ -1,3 +1,5 @@ +import type { FirstDayOfWeek } from '@js/common'; + import type { NormalizedView, SafeSchedulerOptions } from '../utils/options/types'; export interface HeaderOptions { @@ -11,7 +13,7 @@ export interface HeaderOptions { tabIndex?: number; focusStateEnabled?: boolean; useDropDownViewSwitcher: boolean; - firstDayOfWeek?: number; + firstDayOfWeek?: FirstDayOfWeek; toolbar: SafeSchedulerOptions['toolbar']; onCurrentViewChange: (name: string) => void; onCurrentDateChange: (date: Date) => void; @@ -27,3 +29,15 @@ export interface IntervalOptions { intervalCount: number; agendaDuration?: number; } + +export interface SchedulerCalendarProperties { + value: Date; + min?: Date; + max?: Date; + firstDayOfWeek?: FirstDayOfWeek; + focusStateEnabled?: boolean; + tabIndex?: number; + onValueChanged?: (e: { value: Date }) => Promise; +} + +export type EventMapHandler = (value: unknown) => void; diff --git a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts index d4bba916e5ae..8c8fbc051392 100644 --- a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts +++ b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts @@ -28,7 +28,7 @@ import { import { hasWindow } from '@js/core/utils/window'; import DataHelperMixin from '@js/data_helper'; import { custom as customDialog } from '@js/ui/dialog'; -import type { Appointment, AppointmentTooltipShowingEvent } from '@js/ui/scheduler'; +import type { Appointment, AppointmentTooltipShowingEvent, FirstDayOfWeek } from '@js/ui/scheduler'; import errors from '@js/ui/widget/ui.errors'; import { dateUtilsTs } from '@ts/core/utils/date'; @@ -2134,10 +2134,10 @@ class Scheduler extends SchedulerOptionsBaseWidget { } } - getFirstDayOfWeek() { + getFirstDayOfWeek(): FirstDayOfWeek { return isDefined(this.getViewOption('firstDayOfWeek')) - ? this.getViewOption('firstDayOfWeek') - : dateLocalization.firstDayOfWeekIndex(); + ? this.getViewOption('firstDayOfWeek') as FirstDayOfWeek + : dateLocalization.firstDayOfWeekIndex() as FirstDayOfWeek; } _validateKeyFieldIfAgendaExist() { From ec8a94a966d120ff3b1f30155454e0bb8390ce8b Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 13:14:07 +0100 Subject: [PATCH 03/18] feat: add types to m_date_navigator --- .../scheduler/header/m_date_navigator.test.ts | 10 ++++++---- .../js/__internal/scheduler/header/m_date_navigator.ts | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts index 12748972021a..b966e2ed7b57 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts @@ -1,14 +1,16 @@ import { describe, expect, it, jest, } from '@jest/globals'; +import type { ToolbarItem } from '@js/ui/scheduler'; import { CLASS, DEFAULT_ITEMS, getDateNavigator, ITEMS_NAME, } from './m_date_navigator'; +import type { SchedulerHeader } from './m_header'; describe('getDateNavigator', () => { it('should return default options in case of item is empty', () => { - expect(getDateNavigator({} as any, {})).toEqual({ + expect(getDateNavigator({} as SchedulerHeader, {})).toEqual({ location: 'before', name: 'dateNavigator', widget: 'dxButtonGroup', @@ -26,13 +28,13 @@ describe('getDateNavigator', () => { }); }); it('should return replace items in correct order with custom options', () => { - expect(getDateNavigator({} as any, { + expect(getDateNavigator({} as SchedulerHeader, { customField: 'customField', options: { customOption: 'customOption', items: ['dateInterval', 'next', { key: 'customButton' }], }, - } as any)).toEqual({ + } as ToolbarItem)).toEqual({ location: 'before', name: 'dateNavigator', widget: 'dxButtonGroup', @@ -54,7 +56,7 @@ describe('getDateNavigator', () => { it('should handle default and custom click callback', () => { const customClick = jest.fn(); const event = { itemData: { clickHandler: jest.fn() } }; - const config = getDateNavigator({} as any, { + const config = getDateNavigator({} as SchedulerHeader, { options: { onItemClick: customClick }, }); diff --git a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts index 7e9405f55a1f..7bd1d7a89342 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts @@ -31,7 +31,7 @@ const { trimTime } = dateUtils; interface DateNavigatorItem extends ButtonGroupItem { key: string; - clickHandler: (event: ItemClickEvent) => void; + clickHandler: (event: ItemClickEvent) => Promise | void; onContentReady: (event: ContentReadyEvent) => void; } @@ -170,7 +170,7 @@ export const getDateNavigator = (header: SchedulerHeader, item: ToolbarItem): To const options = config.options as ButtonGroupOptions; const { onItemClick } = options; - options.items = (options.items ?? DEFAULT_ITEMS).map((groupItem) => { + options.items = (options.items ?? DEFAULT_ITEMS).map((groupItem: ButtonGroupItem) => { switch (groupItem) { case ITEMS_NAME.previousButton: return getPreviousButtonOptions(header); From 9ec0d4e034f0b6d4653743009435bede94862579 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 13:46:37 +0100 Subject: [PATCH 04/18] refactor: add types to m_utils in header --- .../js/__internal/core/utils/m_date.ts | 7 +- .../js/__internal/scheduler/header/m_utils.ts | 123 +++++++++--------- 2 files changed, 71 insertions(+), 59 deletions(-) diff --git a/packages/devextreme/js/__internal/core/utils/m_date.ts b/packages/devextreme/js/__internal/core/utils/m_date.ts index 897db6958bf4..e3697ef6b11b 100644 --- a/packages/devextreme/js/__internal/core/utils/m_date.ts +++ b/packages/devextreme/js/__internal/core/utils/m_date.ts @@ -134,7 +134,12 @@ const getFirstQuarterMonth = function (month) { return getQuarter(month) * 3; }; -function correctDateWithUnitBeginning(date, dateInterval, withCorrection?, firstDayOfWeek?) { +function correctDateWithUnitBeginning( + date: Date, + dateInterval: typeof dateUnitIntervals[number], + withCorrection?: boolean, + firstDayOfWeek?: number, +): Date { date = new Date(date.getTime()); const oldDate = new Date(date.getTime()); let firstQuarterMonth; diff --git a/packages/devextreme/js/__internal/scheduler/header/m_utils.ts b/packages/devextreme/js/__internal/scheduler/header/m_utils.ts index 7c8770d56997..d358588d4abe 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_utils.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_utils.ts @@ -3,6 +3,7 @@ import dateUtils from '@js/core/utils/date'; import { isFunction, isObject } from '@js/core/utils/type'; import messageLocalization from '@js/localization/message'; import type { DateNavigatorTextInfo, Properties } from '@js/ui/scheduler'; +import type { BaseFormat } from '@ts/core/localization/date'; import { camelize } from '@ts/core/utils/m_inflector'; import type { IntervalOptions, Step } from '@ts/scheduler/header/types'; import type { NormalizedView, RawViewType, ViewType } from '@ts/scheduler/utils/options/types'; @@ -62,7 +63,7 @@ const getDateAfterWorkWeek = (workWeekStart: Date): Date => { let workDaysCount = 0; while (workDaysCount < DAYS_IN_WORK_WEEK) { if (!isWeekend(date)) { - workDaysCount++; + workDaysCount += 1; } date = nextDay(date); @@ -71,56 +72,34 @@ const getDateAfterWorkWeek = (workWeekStart: Date): Date => { return date; }; -const nextAgendaStart = (date: Date, agendaDuration: number): Date => addDateInterval(date, { days: agendaDuration }, 1); +const nextAgendaStart = ( + date: Date, + agendaDuration: number, +): Date => addDateInterval(date, { days: agendaDuration }, 1); -const getIntervalStartDate = (options: IntervalOptions) => { +const getIntervalStartDate = (options: IntervalOptions): Date => { const { date, step, firstDayOfWeek } = options; - // eslint-disable-next-line default-case switch (step) { case 'day': case 'week': case 'month': return getPeriodStart(date, step, false, firstDayOfWeek); case 'workWeek': - // eslint-disable-next-line no-case-declarations - const firstWeekDay = getWeekStart(date, firstDayOfWeek); - return getWorkWeekStart(firstWeekDay); + return getWorkWeekStart(getWeekStart(date, firstDayOfWeek)); case 'agenda': return new Date(date); + default: + return new Date(date); } }; -const getIntervalEndDate = (startDate: Date, options: IntervalOptions) => { - const { intervalCount, step, agendaDuration } = options; - - let periodStartDate; - let periodEndDate; - let nextPeriodStartDate = new Date(startDate); - - for (let i = 0; i < intervalCount; i++) { - periodStartDate = nextPeriodStartDate; - - periodEndDate = getPeriodEndDate(periodStartDate, step, agendaDuration!); - - nextPeriodStartDate = getNextPeriodStartDate(periodEndDate, step); - } - - return periodEndDate; -}; - -export const getCaptionInterval = (options: IntervalOptions): { - startDate: Date; - endDate: Date; -} => { - const startDate = getIntervalStartDate(options); - const endDate = getIntervalEndDate(startDate, options); - - return { startDate, endDate }; -}; - -const getPeriodEndDate = (currentPeriodStartDate: Date, step: Step, agendaDuration: number): Date => { - let date; +const getPeriodEndDate = ( + currentPeriodStartDate: Date, + step: Step, + agendaDuration: number, +): Date => { + let date: Date = new Date(); // eslint-disable-next-line default-case switch (step) { @@ -156,29 +135,22 @@ const getNextPeriodStartDate = (currentPeriodEndDate: Date, step): Date => { return date; }; -export const getNextIntervalDate = (options, direction: Direction): Date => { - const { - date, step, intervalCount, agendaDuration, - } = options; +const getIntervalEndDate = (startDate: Date, options: IntervalOptions): Date => { + const { intervalCount, step, agendaDuration } = options; - let dayDuration; - // eslint-disable-next-line default-case - switch (step) { - case 'day': - dayDuration = Number(intervalCount); - break; - case 'week': - case 'workWeek': - dayDuration = 7 * intervalCount; - break; - case 'agenda': - dayDuration = agendaDuration; - break; - case 'month': - return getNextMonthDate(date, intervalCount, direction); + let periodStartDate = new Date(startDate); + let periodEndDate = new Date(startDate); + let nextPeriodStartDate = new Date(startDate); + + for (let i = 0; i < intervalCount; i += 1) { + periodStartDate = nextPeriodStartDate; + + periodEndDate = getPeriodEndDate(periodStartDate, step, agendaDuration ?? 0); + + nextPeriodStartDate = getNextPeriodStartDate(periodEndDate, step); } - return addDateInterval(date, { days: dayDuration }, direction); + return periodEndDate; }; const getNextMonthDate = (date: Date, intervalCount: number, direction: Direction): Date => { @@ -202,9 +174,34 @@ const getNextMonthDate = (date: Date, intervalCount: number, direction: Directio return thatMonthMinDate; }; +export const getNextIntervalDate = (options: IntervalOptions, direction: Direction): Date => { + const { + date, step, intervalCount, agendaDuration, + } = options; + + let dayDuration = 0; + // eslint-disable-next-line default-case + switch (step) { + case 'day': + dayDuration = Number(intervalCount); + break; + case 'week': + case 'workWeek': + dayDuration = 7 * intervalCount; + break; + case 'agenda': + dayDuration = agendaDuration ?? 0; + break; + case 'month': + return getNextMonthDate(date, intervalCount, direction); + } + + return addDateInterval(date, { days: dayDuration }, direction); +}; + const getDateMonthFormatter = (isShort: boolean) => { const monthType = isShort ? 'abbreviated' : 'wide'; - const months = dateLocalization.getMonthNames(monthType as any); + const months = dateLocalization.getMonthNames(monthType as BaseFormat); return (date: Date): string => { const day = formatDate(date, 'day'); @@ -240,6 +237,16 @@ const getDifferentYearCaption = (startDate: Date, endDate: Date): string => { return `${firstDateText}-${lastDateDateText}`; }; +export const getCaptionInterval = (options: IntervalOptions): { + startDate: Date; + endDate: Date; +} => { + const startDate = getIntervalStartDate(options); + const endDate = getIntervalEndDate(startDate, options); + + return { startDate, endDate }; +}; + const getSameYearCaption = (startDate: Date, endDate: Date, isShort: boolean): string => { const isDifferentMonthDates = startDate.getMonth() !== endDate.getMonth(); const useShortFormat = isDifferentMonthDates || isShort; From 56a217ca6613ad87553bc01bbf389578cb9660c2 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 13:47:54 +0100 Subject: [PATCH 05/18] refactor: move today button to m_date_navigator --- .../scheduler/header/m_date_navigator.ts | 44 ++++++++++++++----- .../__internal/scheduler/header/m_header.ts | 2 +- .../js/__internal/scheduler/header/today.ts | 25 ----------- 3 files changed, 35 insertions(+), 36 deletions(-) delete mode 100644 packages/devextreme/js/__internal/scheduler/header/today.ts diff --git a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts index 7bd1d7a89342..f54f06fb8482 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts @@ -154,6 +154,26 @@ const getNextButtonOptions = (header: SchedulerHeader): DateNavigatorItem => { }; }; +export const getTodayButtonOptions = ( + header: SchedulerHeader, + item: ToolbarItem, +): ToolbarItem => extend(true, {}, { + location: 'before', + locateInMenu: 'auto', + widget: 'dxButton', + cssClass: 'dx-scheduler-today', + options: { + text: messageLocalization.format('dxScheduler-navigationToday'), + icon: 'today', + stylingMode: 'outlined', + type: 'normal', + onClick() { + const headerOptions = header.option(); + header._updateCurrentDate(headerOptions.indicatorTime ?? new Date()); + }, + }, +}, item) as ToolbarItem; + export const getDateNavigator = (header: SchedulerHeader, item: ToolbarItem): ToolbarItem => { // @ts-expect-error current theme used const stylingMode = isMaterialBased() ? 'text' : 'contained'; @@ -170,17 +190,21 @@ export const getDateNavigator = (header: SchedulerHeader, item: ToolbarItem): To const options = config.options as ButtonGroupOptions; const { onItemClick } = options; - options.items = (options.items ?? DEFAULT_ITEMS).map((groupItem: ButtonGroupItem) => { - switch (groupItem) { - case ITEMS_NAME.previousButton: - return getPreviousButtonOptions(header); - case ITEMS_NAME.nextButton: - return getNextButtonOptions(header); - case ITEMS_NAME.calendarButton: - return getCalendarButtonOptions(header); - default: - return groupItem; + const items = (options.items ?? DEFAULT_ITEMS) as (ButtonGroupItem | string)[]; + options.items = items.map((groupItem) => { + if (typeof groupItem === 'string') { + switch (groupItem) { + case ITEMS_NAME.previousButton: + return getPreviousButtonOptions(header); + case ITEMS_NAME.nextButton: + return getNextButtonOptions(header); + case ITEMS_NAME.calendarButton: + return getCalendarButtonOptions(header); + default: + return groupItem as ButtonGroupItem; + } } + return groupItem; }); options.onItemClick = (event): void => { event.itemData.clickHandler?.(event); diff --git a/packages/devextreme/js/__internal/scheduler/header/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/m_header.ts index c08ebe6a9763..47601292901d 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_header.ts @@ -18,6 +18,7 @@ import type { Direction } from './constants'; import SchedulerCalendar from './m_calendar'; import { getDateNavigator, + getTodayButtonOptions, } from './m_date_navigator'; import { getCaption, @@ -29,7 +30,6 @@ import { getDropDownViewSwitcher, getTabViewSwitcher, } from './m_view_switcher'; -import { getTodayButtonOptions } from './today'; import type { EventMapHandler, HeaderOptions, IntervalOptions, SchedulerCalendarProperties, } from './types'; diff --git a/packages/devextreme/js/__internal/scheduler/header/today.ts b/packages/devextreme/js/__internal/scheduler/header/today.ts deleted file mode 100644 index 58bc7581171d..000000000000 --- a/packages/devextreme/js/__internal/scheduler/header/today.ts +++ /dev/null @@ -1,25 +0,0 @@ -import messageLocalization from '@js/common/core/localization/message'; -import type { Item as ToolbarItem } from '@js/ui/toolbar'; -import { extend } from '@ts/core/utils/m_extend'; - -import type { SchedulerHeader } from './m_header'; - -export const getTodayButtonOptions = ( - header: SchedulerHeader, - item: ToolbarItem, -): ToolbarItem => extend(true, {}, { - location: 'before', - locateInMenu: 'auto', - widget: 'dxButton', - cssClass: 'dx-scheduler-today', - options: { - text: messageLocalization.format('dxScheduler-navigationToday'), - icon: 'today', - stylingMode: 'outlined', - type: 'normal', - onClick() { - const headerOptions = header.option(); - header._updateCurrentDate(headerOptions.indicatorTime ?? new Date()); - }, - }, -}, item) as ToolbarItem; From 58d732401a76c63f89df7b863e17b5850de671f6 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 13:52:35 +0100 Subject: [PATCH 06/18] refactor: revert changes to m_date of js/core --- packages/devextreme/js/__internal/core/utils/m_date.ts | 7 +------ .../devextreme/js/__internal/scheduler/header/m_utils.ts | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/devextreme/js/__internal/core/utils/m_date.ts b/packages/devextreme/js/__internal/core/utils/m_date.ts index e3697ef6b11b..897db6958bf4 100644 --- a/packages/devextreme/js/__internal/core/utils/m_date.ts +++ b/packages/devextreme/js/__internal/core/utils/m_date.ts @@ -134,12 +134,7 @@ const getFirstQuarterMonth = function (month) { return getQuarter(month) * 3; }; -function correctDateWithUnitBeginning( - date: Date, - dateInterval: typeof dateUnitIntervals[number], - withCorrection?: boolean, - firstDayOfWeek?: number, -): Date { +function correctDateWithUnitBeginning(date, dateInterval, withCorrection?, firstDayOfWeek?) { date = new Date(date.getTime()); const oldDate = new Date(date.getTime()); let firstQuarterMonth; diff --git a/packages/devextreme/js/__internal/scheduler/header/m_utils.ts b/packages/devextreme/js/__internal/scheduler/header/m_utils.ts index d358588d4abe..2b581c1dc585 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_utils.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_utils.ts @@ -84,7 +84,7 @@ const getIntervalStartDate = (options: IntervalOptions): Date => { case 'day': case 'week': case 'month': - return getPeriodStart(date, step, false, firstDayOfWeek); + return getPeriodStart(date, step, false, firstDayOfWeek) as Date; case 'workWeek': return getWorkWeekStart(getWeekStart(date, firstDayOfWeek)); case 'agenda': From ce2e03aa063cdebfbdae37a299a8c9eeeabde9dd Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 13:54:15 +0100 Subject: [PATCH 07/18] eslint: add strict ts rules to header folder --- packages/devextreme/eslint.config.mjs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/devextreme/eslint.config.mjs b/packages/devextreme/eslint.config.mjs index 03ba17a3e76b..b971ed40dfaa 100644 --- a/packages/devextreme/eslint.config.mjs +++ b/packages/devextreme/eslint.config.mjs @@ -579,6 +579,25 @@ export default [ 'devextreme-custom/no-deferred': 'off', }, }, + // Strict TypeScript rules for scheduler/header + { + files: ['js/__internal/scheduler/header/**/*.ts?(x)'], + languageOptions: { + parser: tsParser, + ecmaVersion: 5, + sourceType: 'script', + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: `${__dirname}/js/__internal`, + }, + }, + rules: { + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/explicit-function-return-type': 'error', + '@typescript-eslint/no-unsafe-return': 'error', + '@typescript-eslint/explicit-module-boundary-types': 'error', + }, + }, // Rules for grid controls { files: [ From 2ea8c2872eba469db9d636015d1c67ad0b7496d6 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 14:10:39 +0100 Subject: [PATCH 08/18] refactor: introduce new folder structure for header --- .../{ => components/calendar}/m_calendar.ts | 2 +- .../header/{ => components}/m_header.ts | 22 +++++++++---------- .../scheduler/header/{ => core}/constants.ts | 0 .../scheduler/header/{ => core}/types.ts | 2 +- .../date-navigator}/m_date_navigator.test.ts | 2 +- .../date-navigator}/m_date_navigator.ts | 4 ++-- .../m_view_switcher.integration.test.ts | 4 ++-- .../view-switcher}/m_view_switcher.ts | 6 ++--- .../header/{m_utils.ts => utils/index.ts} | 4 ++-- .../js/__internal/scheduler/m_scheduler.ts | 4 ++-- 10 files changed, 25 insertions(+), 25 deletions(-) rename packages/devextreme/js/__internal/scheduler/header/{ => components/calendar}/m_calendar.ts (98%) rename packages/devextreme/js/__internal/scheduler/header/{ => components}/m_header.ts (97%) rename packages/devextreme/js/__internal/scheduler/header/{ => core}/constants.ts (100%) rename packages/devextreme/js/__internal/scheduler/header/{ => core}/types.ts (92%) rename packages/devextreme/js/__internal/scheduler/header/{ => features/date-navigator}/m_date_navigator.test.ts (97%) rename packages/devextreme/js/__internal/scheduler/header/{ => features/date-navigator}/m_date_navigator.ts (98%) rename packages/devextreme/js/__internal/scheduler/header/{ => features/view-switcher}/m_view_switcher.integration.test.ts (98%) rename packages/devextreme/js/__internal/scheduler/header/{ => features/view-switcher}/m_view_switcher.ts (95%) rename packages/devextreme/js/__internal/scheduler/header/{m_utils.ts => utils/index.ts} (99%) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts b/packages/devextreme/js/__internal/scheduler/header/components/calendar/m_calendar.ts similarity index 98% rename from packages/devextreme/js/__internal/scheduler/header/m_calendar.ts rename to packages/devextreme/js/__internal/scheduler/header/components/calendar/m_calendar.ts index 3ef28b6776ed..5f2b08b61015 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts +++ b/packages/devextreme/js/__internal/scheduler/header/components/calendar/m_calendar.ts @@ -12,7 +12,7 @@ import type { CalendarProperties } from '@ts/ui/calendar/calendar'; import Calendar from '@ts/ui/calendar/calendar'; import Scrollable from '@ts/ui/scroll_view/scrollable'; -import type { SchedulerCalendarProperties } from './types'; +import type { SchedulerCalendarProperties } from '../../core/types'; const CALENDAR_CLASS = 'dx-scheduler-navigator-calendar'; const CALENDAR_POPOVER_CLASS = 'dx-scheduler-navigator-calendar-popover'; diff --git a/packages/devextreme/js/__internal/scheduler/header/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/components/m_header.ts similarity index 97% rename from packages/devextreme/js/__internal/scheduler/header/m_header.ts rename to packages/devextreme/js/__internal/scheduler/header/components/m_header.ts index 47601292901d..c7739e5ecbb5 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/components/m_header.ts @@ -14,25 +14,25 @@ import type { OptionChanged } from '@ts/core/widget/types'; import Widget from '@ts/core/widget/widget'; import type { NormalizedView, SafeSchedulerOptions } from '@ts/scheduler/utils/options/types'; -import type { Direction } from './constants'; -import SchedulerCalendar from './m_calendar'; +import type { Direction } from '../core/constants'; +import type { + EventMapHandler, HeaderOptions, IntervalOptions, SchedulerCalendarProperties, +} from '../core/types'; import { getDateNavigator, getTodayButtonOptions, -} from './m_date_navigator'; +} from '../features/date-navigator/m_date_navigator'; +import { + getDropDownViewSwitcher, + getTabViewSwitcher, +} from '../features/view-switcher/m_view_switcher'; import { getCaption, getNextIntervalDate, getStep, nextWeek, -} from './m_utils'; -import { - getDropDownViewSwitcher, - getTabViewSwitcher, -} from './m_view_switcher'; -import type { - EventMapHandler, HeaderOptions, IntervalOptions, SchedulerCalendarProperties, -} from './types'; +} from '../utils'; +import SchedulerCalendar from './calendar/m_calendar'; const CLASSES = { component: 'dx-scheduler-header', diff --git a/packages/devextreme/js/__internal/scheduler/header/constants.ts b/packages/devextreme/js/__internal/scheduler/header/core/constants.ts similarity index 100% rename from packages/devextreme/js/__internal/scheduler/header/constants.ts rename to packages/devextreme/js/__internal/scheduler/header/core/constants.ts diff --git a/packages/devextreme/js/__internal/scheduler/header/types.ts b/packages/devextreme/js/__internal/scheduler/header/core/types.ts similarity index 92% rename from packages/devextreme/js/__internal/scheduler/header/types.ts rename to packages/devextreme/js/__internal/scheduler/header/core/types.ts index 17bcb9bae47b..9173d0e843d3 100644 --- a/packages/devextreme/js/__internal/scheduler/header/types.ts +++ b/packages/devextreme/js/__internal/scheduler/header/core/types.ts @@ -1,6 +1,6 @@ import type { FirstDayOfWeek } from '@js/common'; -import type { NormalizedView, SafeSchedulerOptions } from '../utils/options/types'; +import type { NormalizedView, SafeSchedulerOptions } from '../../utils/options/types'; export interface HeaderOptions { currentView: NormalizedView; diff --git a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts b/packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.test.ts similarity index 97% rename from packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts rename to packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.test.ts index b966e2ed7b57..6ce13ab04888 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts +++ b/packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.test.ts @@ -3,10 +3,10 @@ import { } from '@jest/globals'; import type { ToolbarItem } from '@js/ui/scheduler'; +import type { SchedulerHeader } from '../../components/m_header'; import { CLASS, DEFAULT_ITEMS, getDateNavigator, ITEMS_NAME, } from './m_date_navigator'; -import type { SchedulerHeader } from './m_header'; describe('getDateNavigator', () => { it('should return default options in case of item is empty', () => { diff --git a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts b/packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.ts similarity index 98% rename from packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts rename to packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.ts index f54f06fb8482..1f32fd730eab 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts +++ b/packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.ts @@ -6,9 +6,9 @@ import { isMaterialBased } from '@js/ui/themes'; import type { Item as ToolbarItem } from '@js/ui/toolbar'; import { dateUtilsTs } from '@ts/core/utils/date'; import { extend } from '@ts/core/utils/m_extend'; -import type { SchedulerHeader } from '@ts/scheduler/header/m_header'; +import type { SchedulerHeader } from '@ts/scheduler/header/components/m_header'; -import { Direction } from './constants'; +import { Direction } from '../../core/constants'; export const CLASS = { container: 'dx-scheduler-navigator', diff --git a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.integration.test.ts b/packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.integration.test.ts similarity index 98% rename from packages/devextreme/js/__internal/scheduler/header/m_view_switcher.integration.test.ts rename to packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.integration.test.ts index 91309438ba91..e9f3fdb4d68b 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.integration.test.ts +++ b/packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.integration.test.ts @@ -7,8 +7,8 @@ import type { dxElementWrapper } from '@js/core/renderer'; import $ from '@js/core/renderer'; import { loadMessages, locale } from '@js/localization'; -import type { Properties as SchedulerProperties } from '../../../ui/scheduler'; -import Scheduler from '../../../ui/scheduler'; +import type { Properties as SchedulerProperties } from '../../../../../ui/scheduler'; +import Scheduler from '../../../../../ui/scheduler'; const SCHEDULER_CONTAINER_ID = 'schedulerContainer'; diff --git a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts b/packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.ts similarity index 95% rename from packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts rename to packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.ts index 6b29785c04f4..dabaad95618f 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts +++ b/packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.ts @@ -1,12 +1,12 @@ import { isFluent } from '@js/ui/themes'; import type { Item as ToolbarItem } from '@js/ui/toolbar'; -import type { NormalizedView } from '../utils/options/types'; -import type { SchedulerHeader } from './m_header'; +import type { NormalizedView } from '../../../utils/options/types'; +import type { SchedulerHeader } from '../../components/m_header'; import { formatViews, getViewName, -} from './m_utils'; +} from '../../utils'; const ClASS = { container: 'dx-scheduler-view-switcher', diff --git a/packages/devextreme/js/__internal/scheduler/header/m_utils.ts b/packages/devextreme/js/__internal/scheduler/header/utils/index.ts similarity index 99% rename from packages/devextreme/js/__internal/scheduler/header/m_utils.ts rename to packages/devextreme/js/__internal/scheduler/header/utils/index.ts index 2b581c1dc585..8fcb6bc7778e 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_utils.ts +++ b/packages/devextreme/js/__internal/scheduler/header/utils/index.ts @@ -5,10 +5,10 @@ import messageLocalization from '@js/localization/message'; import type { DateNavigatorTextInfo, Properties } from '@js/ui/scheduler'; import type { BaseFormat } from '@ts/core/localization/date'; import { camelize } from '@ts/core/utils/m_inflector'; -import type { IntervalOptions, Step } from '@ts/scheduler/header/types'; +import type { IntervalOptions, Step } from '@ts/scheduler/header/core/types'; import type { NormalizedView, RawViewType, ViewType } from '@ts/scheduler/utils/options/types'; -import type { Direction } from './constants'; +import type { Direction } from '../core/constants'; const DAY_FORMAT = 'd'; diff --git a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts index 8c8fbc051392..653d7a989583 100644 --- a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts +++ b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts @@ -40,8 +40,8 @@ import { ACTION_TO_APPOINTMENT, AppointmentPopup as AppointmentLegacyPopup } fro import { AppointmentPopup } from './appointment_popup/m_popup'; import AppointmentCollection from './appointments/m_appointment_collection'; import NotifyScheduler from './base/m_widget_notify_scheduler'; -import { SchedulerHeader } from './header/m_header'; -import type { HeaderOptions } from './header/types'; +import { SchedulerHeader } from './header/components/m_header'; +import type { HeaderOptions } from './header/core/types'; import { CompactAppointmentsHelper } from './m_compact_appointments_helper'; import { hide as hideLoading, show as showLoading } from './m_loading'; import type { SubscribeKey, SubscribeMethods } from './m_subscribes'; From 1747a0024ce1727ff4eb6a297ea289de76520395 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 14:14:14 +0100 Subject: [PATCH 09/18] Revert "refactor: introduce new folder structure for header" This reverts commit 2ea8c2872eba469db9d636015d1c67ad0b7496d6. --- .../scheduler/header/{core => }/constants.ts | 0 .../{components/calendar => }/m_calendar.ts | 2 +- .../m_date_navigator.test.ts | 2 +- .../date-navigator => }/m_date_navigator.ts | 4 ++-- .../header/{components => }/m_header.ts | 22 +++++++++---------- .../header/{utils/index.ts => m_utils.ts} | 4 ++-- .../m_view_switcher.integration.test.ts | 4 ++-- .../view-switcher => }/m_view_switcher.ts | 6 ++--- .../scheduler/header/{core => }/types.ts | 2 +- .../js/__internal/scheduler/m_scheduler.ts | 4 ++-- 10 files changed, 25 insertions(+), 25 deletions(-) rename packages/devextreme/js/__internal/scheduler/header/{core => }/constants.ts (100%) rename packages/devextreme/js/__internal/scheduler/header/{components/calendar => }/m_calendar.ts (98%) rename packages/devextreme/js/__internal/scheduler/header/{features/date-navigator => }/m_date_navigator.test.ts (97%) rename packages/devextreme/js/__internal/scheduler/header/{features/date-navigator => }/m_date_navigator.ts (98%) rename packages/devextreme/js/__internal/scheduler/header/{components => }/m_header.ts (97%) rename packages/devextreme/js/__internal/scheduler/header/{utils/index.ts => m_utils.ts} (99%) rename packages/devextreme/js/__internal/scheduler/header/{features/view-switcher => }/m_view_switcher.integration.test.ts (98%) rename packages/devextreme/js/__internal/scheduler/header/{features/view-switcher => }/m_view_switcher.ts (95%) rename packages/devextreme/js/__internal/scheduler/header/{core => }/types.ts (92%) diff --git a/packages/devextreme/js/__internal/scheduler/header/core/constants.ts b/packages/devextreme/js/__internal/scheduler/header/constants.ts similarity index 100% rename from packages/devextreme/js/__internal/scheduler/header/core/constants.ts rename to packages/devextreme/js/__internal/scheduler/header/constants.ts diff --git a/packages/devextreme/js/__internal/scheduler/header/components/calendar/m_calendar.ts b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts similarity index 98% rename from packages/devextreme/js/__internal/scheduler/header/components/calendar/m_calendar.ts rename to packages/devextreme/js/__internal/scheduler/header/m_calendar.ts index 5f2b08b61015..3ef28b6776ed 100644 --- a/packages/devextreme/js/__internal/scheduler/header/components/calendar/m_calendar.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts @@ -12,7 +12,7 @@ import type { CalendarProperties } from '@ts/ui/calendar/calendar'; import Calendar from '@ts/ui/calendar/calendar'; import Scrollable from '@ts/ui/scroll_view/scrollable'; -import type { SchedulerCalendarProperties } from '../../core/types'; +import type { SchedulerCalendarProperties } from './types'; const CALENDAR_CLASS = 'dx-scheduler-navigator-calendar'; const CALENDAR_POPOVER_CLASS = 'dx-scheduler-navigator-calendar-popover'; diff --git a/packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.test.ts b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts similarity index 97% rename from packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.test.ts rename to packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts index 6ce13ab04888..b966e2ed7b57 100644 --- a/packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.test.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.test.ts @@ -3,10 +3,10 @@ import { } from '@jest/globals'; import type { ToolbarItem } from '@js/ui/scheduler'; -import type { SchedulerHeader } from '../../components/m_header'; import { CLASS, DEFAULT_ITEMS, getDateNavigator, ITEMS_NAME, } from './m_date_navigator'; +import type { SchedulerHeader } from './m_header'; describe('getDateNavigator', () => { it('should return default options in case of item is empty', () => { diff --git a/packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.ts b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts similarity index 98% rename from packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.ts rename to packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts index 1f32fd730eab..f54f06fb8482 100644 --- a/packages/devextreme/js/__internal/scheduler/header/features/date-navigator/m_date_navigator.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts @@ -6,9 +6,9 @@ import { isMaterialBased } from '@js/ui/themes'; import type { Item as ToolbarItem } from '@js/ui/toolbar'; import { dateUtilsTs } from '@ts/core/utils/date'; import { extend } from '@ts/core/utils/m_extend'; -import type { SchedulerHeader } from '@ts/scheduler/header/components/m_header'; +import type { SchedulerHeader } from '@ts/scheduler/header/m_header'; -import { Direction } from '../../core/constants'; +import { Direction } from './constants'; export const CLASS = { container: 'dx-scheduler-navigator', diff --git a/packages/devextreme/js/__internal/scheduler/header/components/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/m_header.ts similarity index 97% rename from packages/devextreme/js/__internal/scheduler/header/components/m_header.ts rename to packages/devextreme/js/__internal/scheduler/header/m_header.ts index c7739e5ecbb5..47601292901d 100644 --- a/packages/devextreme/js/__internal/scheduler/header/components/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_header.ts @@ -14,25 +14,25 @@ import type { OptionChanged } from '@ts/core/widget/types'; import Widget from '@ts/core/widget/widget'; import type { NormalizedView, SafeSchedulerOptions } from '@ts/scheduler/utils/options/types'; -import type { Direction } from '../core/constants'; -import type { - EventMapHandler, HeaderOptions, IntervalOptions, SchedulerCalendarProperties, -} from '../core/types'; +import type { Direction } from './constants'; +import SchedulerCalendar from './m_calendar'; import { getDateNavigator, getTodayButtonOptions, -} from '../features/date-navigator/m_date_navigator'; -import { - getDropDownViewSwitcher, - getTabViewSwitcher, -} from '../features/view-switcher/m_view_switcher'; +} from './m_date_navigator'; import { getCaption, getNextIntervalDate, getStep, nextWeek, -} from '../utils'; -import SchedulerCalendar from './calendar/m_calendar'; +} from './m_utils'; +import { + getDropDownViewSwitcher, + getTabViewSwitcher, +} from './m_view_switcher'; +import type { + EventMapHandler, HeaderOptions, IntervalOptions, SchedulerCalendarProperties, +} from './types'; const CLASSES = { component: 'dx-scheduler-header', diff --git a/packages/devextreme/js/__internal/scheduler/header/utils/index.ts b/packages/devextreme/js/__internal/scheduler/header/m_utils.ts similarity index 99% rename from packages/devextreme/js/__internal/scheduler/header/utils/index.ts rename to packages/devextreme/js/__internal/scheduler/header/m_utils.ts index 8fcb6bc7778e..2b581c1dc585 100644 --- a/packages/devextreme/js/__internal/scheduler/header/utils/index.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_utils.ts @@ -5,10 +5,10 @@ import messageLocalization from '@js/localization/message'; import type { DateNavigatorTextInfo, Properties } from '@js/ui/scheduler'; import type { BaseFormat } from '@ts/core/localization/date'; import { camelize } from '@ts/core/utils/m_inflector'; -import type { IntervalOptions, Step } from '@ts/scheduler/header/core/types'; +import type { IntervalOptions, Step } from '@ts/scheduler/header/types'; import type { NormalizedView, RawViewType, ViewType } from '@ts/scheduler/utils/options/types'; -import type { Direction } from '../core/constants'; +import type { Direction } from './constants'; const DAY_FORMAT = 'd'; diff --git a/packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.integration.test.ts b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.integration.test.ts similarity index 98% rename from packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.integration.test.ts rename to packages/devextreme/js/__internal/scheduler/header/m_view_switcher.integration.test.ts index e9f3fdb4d68b..91309438ba91 100644 --- a/packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.integration.test.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.integration.test.ts @@ -7,8 +7,8 @@ import type { dxElementWrapper } from '@js/core/renderer'; import $ from '@js/core/renderer'; import { loadMessages, locale } from '@js/localization'; -import type { Properties as SchedulerProperties } from '../../../../../ui/scheduler'; -import Scheduler from '../../../../../ui/scheduler'; +import type { Properties as SchedulerProperties } from '../../../ui/scheduler'; +import Scheduler from '../../../ui/scheduler'; const SCHEDULER_CONTAINER_ID = 'schedulerContainer'; diff --git a/packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.ts b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts similarity index 95% rename from packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.ts rename to packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts index dabaad95618f..6b29785c04f4 100644 --- a/packages/devextreme/js/__internal/scheduler/header/features/view-switcher/m_view_switcher.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts @@ -1,12 +1,12 @@ import { isFluent } from '@js/ui/themes'; import type { Item as ToolbarItem } from '@js/ui/toolbar'; -import type { NormalizedView } from '../../../utils/options/types'; -import type { SchedulerHeader } from '../../components/m_header'; +import type { NormalizedView } from '../utils/options/types'; +import type { SchedulerHeader } from './m_header'; import { formatViews, getViewName, -} from '../../utils'; +} from './m_utils'; const ClASS = { container: 'dx-scheduler-view-switcher', diff --git a/packages/devextreme/js/__internal/scheduler/header/core/types.ts b/packages/devextreme/js/__internal/scheduler/header/types.ts similarity index 92% rename from packages/devextreme/js/__internal/scheduler/header/core/types.ts rename to packages/devextreme/js/__internal/scheduler/header/types.ts index 9173d0e843d3..17bcb9bae47b 100644 --- a/packages/devextreme/js/__internal/scheduler/header/core/types.ts +++ b/packages/devextreme/js/__internal/scheduler/header/types.ts @@ -1,6 +1,6 @@ import type { FirstDayOfWeek } from '@js/common'; -import type { NormalizedView, SafeSchedulerOptions } from '../../utils/options/types'; +import type { NormalizedView, SafeSchedulerOptions } from '../utils/options/types'; export interface HeaderOptions { currentView: NormalizedView; diff --git a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts index 653d7a989583..8c8fbc051392 100644 --- a/packages/devextreme/js/__internal/scheduler/m_scheduler.ts +++ b/packages/devextreme/js/__internal/scheduler/m_scheduler.ts @@ -40,8 +40,8 @@ import { ACTION_TO_APPOINTMENT, AppointmentPopup as AppointmentLegacyPopup } fro import { AppointmentPopup } from './appointment_popup/m_popup'; import AppointmentCollection from './appointments/m_appointment_collection'; import NotifyScheduler from './base/m_widget_notify_scheduler'; -import { SchedulerHeader } from './header/components/m_header'; -import type { HeaderOptions } from './header/core/types'; +import { SchedulerHeader } from './header/m_header'; +import type { HeaderOptions } from './header/types'; import { CompactAppointmentsHelper } from './m_compact_appointments_helper'; import { hide as hideLoading, show as showLoading } from './m_loading'; import type { SubscribeKey, SubscribeMethods } from './m_subscribes'; From bb9648fa4db179b84ee11ffddbba0727ddada034 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 15:42:33 +0100 Subject: [PATCH 10/18] fix: fix bug --- .../js/__internal/scheduler/header/m_calendar.ts | 7 +++---- .../devextreme/js/__internal/scheduler/header/types.ts | 5 ++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts index 3ef28b6776ed..0a377db28e0d 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts @@ -22,7 +22,7 @@ const CALENDAR_POPOVER_CLASS = 'dx-scheduler-navigator-calendar-popover'; * It shows a popup/popover with a calendar widget for date selection. */ export default class SchedulerCalendar extends Widget< -SchedulerProperties & SchedulerCalendarProperties + SchedulerProperties & SchedulerCalendarProperties > { _overlay: Popup | Popover | undefined; @@ -124,14 +124,13 @@ SchedulerProperties & SchedulerCalendarProperties _getCalendarOptions(): CalendarProperties { const schedulerOptions = this.option(); return { - value: schedulerOptions.currentDate, + value: schedulerOptions.value, min: schedulerOptions.min, max: schedulerOptions.max, firstDayOfWeek: schedulerOptions.firstDayOfWeek, focusStateEnabled: schedulerOptions.focusStateEnabled, tabIndex: schedulerOptions.tabIndex, - // @ts-expect-error onCurrentDateChange exists in HeaderOptions but not in Scheduler types - onValueChanged: schedulerOptions.onCurrentDateChange, + onValueChanged: schedulerOptions.onValueChanged, // @ts-expect-error skipFocusCheck is an internal Calendar property skipFocusCheck: true, }; diff --git a/packages/devextreme/js/__internal/scheduler/header/types.ts b/packages/devextreme/js/__internal/scheduler/header/types.ts index 17bcb9bae47b..c29ae8a0a3e8 100644 --- a/packages/devextreme/js/__internal/scheduler/header/types.ts +++ b/packages/devextreme/js/__internal/scheduler/header/types.ts @@ -1,4 +1,7 @@ import type { FirstDayOfWeek } from '@js/common'; +import type { NativeEventInfo } from '@js/common/core/events'; +import type dxCalendar from '@js/ui/calendar'; +import type { ValueChangedInfo } from '@js/ui/editor/editor'; import type { NormalizedView, SafeSchedulerOptions } from '../utils/options/types'; @@ -37,7 +40,7 @@ export interface SchedulerCalendarProperties { firstDayOfWeek?: FirstDayOfWeek; focusStateEnabled?: boolean; tabIndex?: number; - onValueChanged?: (e: { value: Date }) => Promise; + onValueChanged?: (e: (NativeEventInfo & ValueChangedInfo)) => void; } export type EventMapHandler = (value: unknown) => void; From 2e72021546f7f8aab53415f6b3098dc11135ee1b Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Wed, 21 Jan 2026 16:34:05 +0100 Subject: [PATCH 11/18] fix: fix ts lint --- .../devextreme/js/__internal/scheduler/header/m_header.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/m_header.ts index 47601292901d..d5b981e0c9f8 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_header.ts @@ -241,9 +241,10 @@ export class SchedulerHeader extends Widget { firstDayOfWeek: headerOptions.firstDayOfWeek, focusStateEnabled: headerOptions.focusStateEnabled, tabIndex: headerOptions.tabIndex, - onValueChanged: async (e) => { + onValueChanged: (e) => { this._updateCurrentDate(e.value); - await this._calendar?.hide(); + // eslint-disable-next-line @typescript-eslint/no-floating-promises + this._calendar?.hide(); }, }); From a312599fefc658f88866ab7bf5e25f8b21d2d4f4 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 22 Jan 2026 09:50:29 +0100 Subject: [PATCH 12/18] refactor: small updates to syntax --- .../__internal/scheduler/header/m_calendar.ts | 39 +++++----- .../scheduler/header/m_date_navigator.ts | 4 +- .../__internal/scheduler/header/m_header.ts | 74 +++++++++---------- .../scheduler/header/m_view_switcher.ts | 8 +- .../js/__internal/scheduler/header/types.ts | 8 +- 5 files changed, 61 insertions(+), 72 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts index 0a377db28e0d..b58cb008bc43 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts @@ -5,28 +5,21 @@ import $ from '@js/core/renderer'; import type { DateLike } from '@js/ui/calendar'; import Popover from '@js/ui/popover/ui.popover'; import Popup from '@js/ui/popup/ui.popup'; -import type { Properties as SchedulerProperties } from '@js/ui/scheduler'; import Widget from '@ts/core/widget/widget'; import type { KeyboardKeyDownEvent } from '@ts/events/core/m_keyboard_processor'; import type { CalendarProperties } from '@ts/ui/calendar/calendar'; import Calendar from '@ts/ui/calendar/calendar'; import Scrollable from '@ts/ui/scroll_view/scrollable'; -import type { SchedulerCalendarProperties } from './types'; +import type { SchedulerCalendarOptions } from './types'; const CALENDAR_CLASS = 'dx-scheduler-navigator-calendar'; const CALENDAR_POPOVER_CLASS = 'dx-scheduler-navigator-calendar-popover'; -/** - * Calendar component that is displayed when clicking on the date navigator in the scheduler header. - * It shows a popup/popover with a calendar widget for date selection. - */ -export default class SchedulerCalendar extends Widget< - SchedulerProperties & SchedulerCalendarProperties -> { - _overlay: Popup | Popover | undefined; +export default class SchedulerCalendar extends Widget { + _overlay?: Popup | Popover; - _calendar: Calendar | undefined; + _calendar?: Calendar; async show(target: HTMLElement): Promise { if (!SchedulerCalendar._isMobileLayout()) { @@ -61,8 +54,8 @@ export default class SchedulerCalendar extends Widget< const isMobileLayout = SchedulerCalendar._isMobileLayout(); const overlayConfig = { - contentTemplate: () => this._createOverlayContent(), - onShown: () => { + contentTemplate: (): dxElementWrapper => this._createOverlayContent(), + onShown: (): void => { this._calendar?.focus(); }, defaultOptionsRules: [ @@ -78,7 +71,7 @@ export default class SchedulerCalendar extends Widget< }, }, ], - } as const; + }; if (isMobileLayout) { this._overlay = this._createComponent(this.$element(), Popup, overlayConfig); @@ -122,15 +115,17 @@ export default class SchedulerCalendar extends Widget< } _getCalendarOptions(): CalendarProperties { - const schedulerOptions = this.option(); + const { + value, min, max, firstDayOfWeek, focusStateEnabled, tabIndex, onValueChanged, + } = this.option(); return { - value: schedulerOptions.value, - min: schedulerOptions.min, - max: schedulerOptions.max, - firstDayOfWeek: schedulerOptions.firstDayOfWeek, - focusStateEnabled: schedulerOptions.focusStateEnabled, - tabIndex: schedulerOptions.tabIndex, - onValueChanged: schedulerOptions.onValueChanged, + value, + min, + max, + firstDayOfWeek, + focusStateEnabled, + tabIndex, + onValueChanged, // @ts-expect-error skipFocusCheck is an internal Calendar property skipFocusCheck: true, }; diff --git a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts index f54f06fb8482..386fcc0d9a08 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts @@ -168,8 +168,8 @@ export const getTodayButtonOptions = ( stylingMode: 'outlined', type: 'normal', onClick() { - const headerOptions = header.option(); - header._updateCurrentDate(headerOptions.indicatorTime ?? new Date()); + const { indicatorTime } = header.option(); + header._updateCurrentDate(indicatorTime ?? new Date()); }, }, }, item) as ToolbarItem; diff --git a/packages/devextreme/js/__internal/scheduler/header/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/m_header.ts index d5b981e0c9f8..8ac2dfa6eb2a 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_header.ts @@ -31,7 +31,7 @@ import { getTabViewSwitcher, } from './m_view_switcher'; import type { - EventMapHandler, HeaderOptions, IntervalOptions, SchedulerCalendarProperties, + EventMapHandler, HeaderOptions, IntervalOptions, SchedulerCalendarOptions, } from './types'; const CLASSES = { @@ -49,15 +49,14 @@ export class SchedulerHeader extends Widget { _toolbar!: Toolbar; - _calendar: SchedulerCalendar | undefined; + _calendar?: SchedulerCalendar; get captionText(): string { return this._getCaption().text; } getIntervalOptions(date: Date): IntervalOptions { - const headerOptions = this.option(); - const { currentView, firstDayOfWeek } = headerOptions; + const { currentView, firstDayOfWeek } = this.option(); const step = getStep(currentView.type); return { @@ -160,10 +159,9 @@ export class SchedulerHeader extends Widget { } _toggleVisibility(): void { - const headerOptions = this.option(); - const toolbarOptions = headerOptions.toolbar; - const isHeaderShown = toolbarOptions.visible - ?? (toolbarOptions.visible === undefined && toolbarOptions.items.length); + const { toolbar } = this.option(); + const isHeaderShown = toolbar.visible + ?? (toolbar.visible === undefined && toolbar.items.length); if (isHeaderShown) { this.$element().removeClass(CLASSES.invisible); @@ -173,12 +171,11 @@ export class SchedulerHeader extends Widget { } _createToolbarConfig(): SafeSchedulerOptions['toolbar'] { - const headerOptions = this.option(); - const options = headerOptions.toolbar; - const parsedItems = options.items.map((element) => this._parseItem(element)); + const { toolbar } = this.option(); + const parsedItems = toolbar.items.map((element) => this._parseItem(element)); return { - ...options, + ...toolbar, items: parsedItems, }; } @@ -217,8 +214,8 @@ export class SchedulerHeader extends Widget { } _updateCurrentView(view: Required): void { - const headerOptions = this.option(); - headerOptions.onCurrentViewChange(view.name); + const { onCurrentViewChange } = this.option(); + onCurrentViewChange(view.name); } _updateCalendarValueAndCurrentDate(date: Date): void { @@ -227,32 +224,33 @@ export class SchedulerHeader extends Widget { } _updateCurrentDate(date: Date): void { - const headerOptions = this.option(); - headerOptions.onCurrentDateChange(date); + const { onCurrentDateChange } = this.option(); + onCurrentDateChange(date); this._callEvent('currentDate', date); } _renderCalendar(): void { - const headerOptions = this.option(); + const { + currentDate, min, max, firstDayOfWeek, focusStateEnabled, tabIndex, + } = this.option(); this._calendar = this._createComponent('
', SchedulerCalendar, { - value: headerOptions.currentDate, - min: headerOptions.min, - max: headerOptions.max, - firstDayOfWeek: headerOptions.firstDayOfWeek, - focusStateEnabled: headerOptions.focusStateEnabled, - tabIndex: headerOptions.tabIndex, - onValueChanged: (e) => { + value: currentDate, + min, + max, + firstDayOfWeek, + focusStateEnabled, + tabIndex, + onValueChanged: async (e) => { this._updateCurrentDate(e.value); - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this._calendar?.hide(); + await this._calendar?.hide(); }, }); this._calendar.$element().appendTo(this.$element()); } - _getCalendarOptionUpdater(name: keyof SchedulerCalendarProperties) { - return (value: SchedulerCalendarProperties[typeof name]): void => { + _getCalendarOptionUpdater(name: keyof SchedulerCalendarOptions) { + return (value: SchedulerCalendarOptions[typeof name]): void => { if (this._calendar) { this._calendar.option(name, value); } @@ -260,26 +258,25 @@ export class SchedulerHeader extends Widget { } _getNextDate(direction: Direction, initialDate?: Date): Date { - const headerOptions = this.option(); - const date = initialDate ?? headerOptions.currentDate; + const { currentDate } = this.option(); + const date = initialDate ?? currentDate; const options = this.getIntervalOptions(date); return getNextIntervalDate(options, direction); } _getDisplayedDate(): Date { - const headerOptions = this.option(); - const startViewDate = new Date(headerOptions.startViewDate); - const isMonth = headerOptions.currentView.type === 'month'; + const { startViewDate, currentView } = this.option(); + const isMonth = currentView.type === 'month'; return isMonth ? nextWeek(startViewDate) : startViewDate; } _getCaptionOptions(): IntervalOptions { - const headerOptions = this.option(); - let date = headerOptions.currentDate; + const { currentDate, startViewDate } = this.option(); + let date = currentDate; - if (headerOptions.startViewDate) { + if (startViewDate) { date = this._getDisplayedDate(); } @@ -289,12 +286,11 @@ export class SchedulerHeader extends Widget { } _getCaption(): DateNavigatorTextInfo { - const headerOptions = this.option(); + const { customizeDateNavigatorText } = this.option(); const options = this._getCaptionOptions(); - const customizationFunction = headerOptions.customizeDateNavigatorText; const useShortDateFormat = this.option('_useShortDateFormat'); - return getCaption(options, Boolean(useShortDateFormat), customizationFunction); + return getCaption(options, Boolean(useShortDateFormat), customizeDateNavigatorText); } _updateDateByDirection(direction: Direction): void { diff --git a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts index 6b29785c04f4..e89927e9c209 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts @@ -19,10 +19,10 @@ const getViewsAndSelectedView = (header: SchedulerHeader): selectedView: string | undefined; views: NormalizedView[]; } => { - const headerOptions = header.option(); - const views = formatViews(headerOptions.views); - const selectedView = getViewName(headerOptions.currentView); - const isSelectedViewInViews = views.some((view) => view.name === selectedView); + const { views, currentView } = header.option(); + const formattedViews = formatViews(views); + const selectedView = getViewName(currentView); + const isSelectedViewInViews = formattedViews.some((view) => view.name === selectedView); return { selectedView: isSelectedViewInViews ? selectedView : undefined, diff --git a/packages/devextreme/js/__internal/scheduler/header/types.ts b/packages/devextreme/js/__internal/scheduler/header/types.ts index c29ae8a0a3e8..35dc937aded0 100644 --- a/packages/devextreme/js/__internal/scheduler/header/types.ts +++ b/packages/devextreme/js/__internal/scheduler/header/types.ts @@ -1,7 +1,5 @@ import type { FirstDayOfWeek } from '@js/common'; -import type { NativeEventInfo } from '@js/common/core/events'; -import type dxCalendar from '@js/ui/calendar'; -import type { ValueChangedInfo } from '@js/ui/editor/editor'; +import type { ValueChangedEvent } from '@js/ui/calendar'; import type { NormalizedView, SafeSchedulerOptions } from '../utils/options/types'; @@ -33,14 +31,14 @@ export interface IntervalOptions { agendaDuration?: number; } -export interface SchedulerCalendarProperties { +export interface SchedulerCalendarOptions { value: Date; min?: Date; max?: Date; firstDayOfWeek?: FirstDayOfWeek; focusStateEnabled?: boolean; tabIndex?: number; - onValueChanged?: (e: (NativeEventInfo & ValueChangedInfo)) => void; + onValueChanged?: (e: ValueChangedEvent) => void; } export type EventMapHandler = (value: unknown) => void; From 0dc2548df95240cc4a35916863366a76e1d068a1 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 22 Jan 2026 10:54:58 +0100 Subject: [PATCH 13/18] refactor: small updates to syntax --- .../scheduler/header/m_date_navigator.ts | 30 ++++++++----------- .../scheduler/header/m_view_switcher.ts | 5 ++-- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts index 386fcc0d9a08..7894ae76b3ed 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_date_navigator.ts @@ -2,7 +2,7 @@ import messageLocalization from '@js/common/core/localization/message'; import dateUtils from '@js/core/utils/date'; import type { ContentReadyEvent } from '@js/ui/button'; import type { Item as ButtonGroupItem, ItemClickEvent, Properties as ButtonGroupOptions } from '@js/ui/button_group'; -import { isMaterialBased } from '@js/ui/themes'; +import { current, isMaterialBased } from '@js/ui/themes'; import type { Item as ToolbarItem } from '@js/ui/toolbar'; import { dateUtilsTs } from '@ts/core/utils/date'; import { extend } from '@ts/core/utils/m_extend'; @@ -175,8 +175,7 @@ export const getTodayButtonOptions = ( }, item) as ToolbarItem; export const getDateNavigator = (header: SchedulerHeader, item: ToolbarItem): ToolbarItem => { - // @ts-expect-error current theme used - const stylingMode = isMaterialBased() ? 'text' : 'contained'; + const stylingMode = isMaterialBased(current()) ? 'text' : 'contained'; const config: ToolbarItem = extend(true, {}, { location: 'before', name: 'dateNavigator', @@ -190,21 +189,18 @@ export const getDateNavigator = (header: SchedulerHeader, item: ToolbarItem): To const options = config.options as ButtonGroupOptions; const { onItemClick } = options; - const items = (options.items ?? DEFAULT_ITEMS) as (ButtonGroupItem | string)[]; - options.items = items.map((groupItem) => { - if (typeof groupItem === 'string') { - switch (groupItem) { - case ITEMS_NAME.previousButton: - return getPreviousButtonOptions(header); - case ITEMS_NAME.nextButton: - return getNextButtonOptions(header); - case ITEMS_NAME.calendarButton: - return getCalendarButtonOptions(header); - default: - return groupItem as ButtonGroupItem; - } + const items = (options.items ?? DEFAULT_ITEMS); + options.items = items.map((groupItem: ButtonGroupItem | string) => { + switch (groupItem) { + case ITEMS_NAME.previousButton: + return getPreviousButtonOptions(header); + case ITEMS_NAME.nextButton: + return getNextButtonOptions(header); + case ITEMS_NAME.calendarButton: + return getCalendarButtonOptions(header); + default: + return groupItem as ButtonGroupItem; } - return groupItem; }); options.onItemClick = (event): void => { event.itemData.clickHandler?.(event); diff --git a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts index e89927e9c209..eb90d6d0995f 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts @@ -1,4 +1,4 @@ -import { isFluent } from '@js/ui/themes'; +import { current, isFluent } from '@js/ui/themes'; import type { Item as ToolbarItem } from '@js/ui/toolbar'; import type { NormalizedView } from '../utils/options/types'; @@ -39,8 +39,7 @@ export const getTabViewSwitcher = ( const { selectedView, views } = getViewsAndSelectedView(header); const isVisible = isViewSwitcherVisible(views); - // @ts-expect-error - const stylingMode = isFluent() ? 'outlined' : 'contained'; + const stylingMode = isFluent(current()) ? 'outlined' : 'contained'; return { widget: 'dxButtonGroup', From ebf6cec2962d8a932ab1c9b305c4f36a025a199b Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 22 Jan 2026 11:32:31 +0100 Subject: [PATCH 14/18] refactor: small updates to syntax --- .../js/__internal/scheduler/header/m_header.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/m_header.ts index 8ac2dfa6eb2a..5ca5e4f09abd 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_header.ts @@ -47,7 +47,7 @@ const ITEM_NAMES = { export class SchedulerHeader extends Widget { eventMap!: Map; - _toolbar!: Toolbar; + _toolbar?: Toolbar; _calendar?: SchedulerCalendar; @@ -85,7 +85,7 @@ export class SchedulerHeader extends Widget { ['focusStateEnabled', [this.repaint.bind(this)]], ['useDropDownViewSwitcher', [this.repaint.bind(this)]], ['indicatorTime', []], - ] as unknown as [string, EventMapHandler[]][]); + ] as [string, EventMapHandler[]][]); } _addEvent(name: string, event: EventMapHandler): void { @@ -121,16 +121,16 @@ export class SchedulerHeader extends Widget { this.repaint(); break; case fullName === 'toolbar.items': - this._toolbar.option( + this._toolbar?.option( 'items', (value as []).map((item: ToolbarItem) => this._parseItem(item)), ); break; case parts[1] === 'items' && parts.length === 3: - this._toolbar.option(optionName, this._parseItem(value as ToolbarItem)); + this._toolbar?.option(optionName, this._parseItem(value as ToolbarItem)); break; default: - this._toolbar.option(optionName, value); + this._toolbar?.option(optionName, value); } } From 097b90ab201f032429ac25230373d12829da3ad3 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 22 Jan 2026 11:34:32 +0100 Subject: [PATCH 15/18] refactor: rename scheduler calendar header type --- .../js/__internal/scheduler/header/m_calendar.ts | 4 ++-- .../devextreme/js/__internal/scheduler/header/m_header.ts | 7 ++++--- .../devextreme/js/__internal/scheduler/header/types.ts | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts index b58cb008bc43..4aed71418c43 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_calendar.ts @@ -11,12 +11,12 @@ import type { CalendarProperties } from '@ts/ui/calendar/calendar'; import Calendar from '@ts/ui/calendar/calendar'; import Scrollable from '@ts/ui/scroll_view/scrollable'; -import type { SchedulerCalendarOptions } from './types'; +import type { HeaderCalendarOptions } from './types'; const CALENDAR_CLASS = 'dx-scheduler-navigator-calendar'; const CALENDAR_POPOVER_CLASS = 'dx-scheduler-navigator-calendar-popover'; -export default class SchedulerCalendar extends Widget { +export default class SchedulerCalendar extends Widget { _overlay?: Popup | Popover; _calendar?: Calendar; diff --git a/packages/devextreme/js/__internal/scheduler/header/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/m_header.ts index 5ca5e4f09abd..7de48de97053 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_header.ts @@ -31,7 +31,8 @@ import { getTabViewSwitcher, } from './m_view_switcher'; import type { - EventMapHandler, HeaderOptions, IntervalOptions, SchedulerCalendarOptions, + EventMapHandler, HeaderCalendarOptions, + HeaderOptions, IntervalOptions, } from './types'; const CLASSES = { @@ -249,8 +250,8 @@ export class SchedulerHeader extends Widget { this._calendar.$element().appendTo(this.$element()); } - _getCalendarOptionUpdater(name: keyof SchedulerCalendarOptions) { - return (value: SchedulerCalendarOptions[typeof name]): void => { + _getCalendarOptionUpdater(name: keyof HeaderCalendarOptions) { + return (value: HeaderCalendarOptions[typeof name]): void => { if (this._calendar) { this._calendar.option(name, value); } diff --git a/packages/devextreme/js/__internal/scheduler/header/types.ts b/packages/devextreme/js/__internal/scheduler/header/types.ts index 35dc937aded0..0481ff50a903 100644 --- a/packages/devextreme/js/__internal/scheduler/header/types.ts +++ b/packages/devextreme/js/__internal/scheduler/header/types.ts @@ -31,7 +31,7 @@ export interface IntervalOptions { agendaDuration?: number; } -export interface SchedulerCalendarOptions { +export interface HeaderCalendarOptions { value: Date; min?: Date; max?: Date; From dd4dc57cd748e6c0dd18fd4b249001db41e2e496 Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 22 Jan 2026 12:00:27 +0100 Subject: [PATCH 16/18] fix: fix build --- .../js/__internal/scheduler/header/m_view_switcher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts index eb90d6d0995f..8b98db201586 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_view_switcher.ts @@ -26,7 +26,7 @@ const getViewsAndSelectedView = (header: SchedulerHeader): return { selectedView: isSelectedViewInViews ? selectedView : undefined, - views, + views: formattedViews, }; }; From 7e10d9437522a358cfd00f74afd601e596b5387c Mon Sep 17 00:00:00 2001 From: Sergio Bur Date: Thu, 22 Jan 2026 13:01:11 +0100 Subject: [PATCH 17/18] refactor: small updates to syntax --- .../devextreme/js/__internal/scheduler/header/m_header.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/m_header.ts index 7de48de97053..0b3b8d439f90 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_header.ts @@ -31,7 +31,7 @@ import { getTabViewSwitcher, } from './m_view_switcher'; import type { - EventMapHandler, HeaderCalendarOptions, + EventMapHandler, HeaderOptions, IntervalOptions, } from './types'; @@ -250,8 +250,8 @@ export class SchedulerHeader extends Widget { this._calendar.$element().appendTo(this.$element()); } - _getCalendarOptionUpdater(name: keyof HeaderCalendarOptions) { - return (value: HeaderCalendarOptions[typeof name]): void => { + _getCalendarOptionUpdater(name: string) { + return (value: unknown): void => { if (this._calendar) { this._calendar.option(name, value); } From c5434c17bc6356271828515ee0511f39b327b438 Mon Sep 17 00:00:00 2001 From: Sergei Burkatskii Date: Thu, 22 Jan 2026 15:07:12 +0100 Subject: [PATCH 18/18] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Sergei Burkatskii --- packages/devextreme/js/__internal/scheduler/header/m_header.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme/js/__internal/scheduler/header/m_header.ts b/packages/devextreme/js/__internal/scheduler/header/m_header.ts index 0b3b8d439f90..cc0f549dc9e7 100644 --- a/packages/devextreme/js/__internal/scheduler/header/m_header.ts +++ b/packages/devextreme/js/__internal/scheduler/header/m_header.ts @@ -209,7 +209,7 @@ export class SchedulerHeader extends Widget { if (this.eventMap.has(event)) { const events = this.eventMap.get(event); if (events) { - events.forEach((EventMapHandler) => EventMapHandler(arg)); + events.forEach((eventMapHandler) => eventMapHandler(arg)); } } }