UNPKG

devextreme

Version:

JavaScript/TypeScript Component Suite for Responsive Web Development

190 lines (188 loc) 7.28 kB
/** * DevExtreme (cjs/__internal/scheduler/appointments/m_appointments_kbn.js) * Version: 26.1.4 * Build date: Fri Jul 24 2026 * * Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AppointmentsKeyboardNavigation = void 0; var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _common = require("../../../core/utils/common"); var _m_element = require("../../core/m_element"); var _m_events_engine = _interopRequireDefault(require("../../events/core/m_events_engine")); var _is_focus_lost = require("../utils/is_focus_lost"); var _appointment_groups_utils = require("../utils/resource_manager/appointment_groups_utils"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } class AppointmentsKeyboardNavigation { constructor(collection) { this.focusedItemSortIndex = -1; this.isNavigating = false; this.pendingDeleteFocusSortedIndex = -1; this._collection = collection } getFocusableItems() { const appts = this._collection._itemElements().not(".dx-state-disabled"); const collectors = this._collection.$element().find(".dx-scheduler-appointment-collector"); return appts.add(collectors) } focus($item) { const $target = $item ?? this.$focusTarget(); if ($target.length) { _m_events_engine.default.trigger($target, "focus") } } $focusTarget() { const $items = this._collection.$itemBySortedIndex; if (!$items) { return (0, _renderer.default)() } const $item = $items[this.focusedItemSortIndex]; return $item || (0, _renderer.default)() } resetTabIndex($item) { const $target = $item ?? this.$focusTarget(); this.getFocusableItems().attr("tabIndex", -1); $target.attr("tabIndex", this._collection.option("tabIndex")) } focusInHandler(e) { const $target = (0, _renderer.default)(e.target); const itemData = this._collection.getAppointmentSettings($target); if (!itemData) { return } this.focusedItemSortIndex = itemData.sortedIndex; this._collection.option("focusedElement", (0, _m_element.getPublicElement)(e.target)) } focusOutHandler() { this._collection.option("focusedElement", (0, _m_element.getPublicElement)(this.getFirstVisibleItem())) } getSupportedKeys() { return { escape: this.escHandler.bind(this), del: this.delHandler.bind(this), tab: this.tabHandler.bind(this), home: this.homeHandler.bind(this), end: this.endHandler.bind(this) } } delHandler(e) { if (this._collection.option("allowDelete")) { e.preventDefault(); const settings = this._collection.getAppointmentSettings((0, _renderer.default)(e.target)); this.pendingDeleteFocusSortedIndex = settings.sortedIndex; this._collection.notifyObserver("onDeleteButtonPress", { data: settings.itemData, target: e.target }) } } onItemsRendered() { const pendingIndex = this.pendingDeleteFocusSortedIndex; this.pendingDeleteFocusSortedIndex = -1; if (pendingIndex < 0) { return } Promise.resolve().then(() => { this.restoreFocusAfterDelete(pendingIndex) }).catch(_common.noop) } restoreFocusAfterDelete(sortedIndex) { if (!(0, _is_focus_lost.isFocusLost)()) { return } const $item = this.findNearestItem(sortedIndex); if ($item) { this.focus($item); return } this._collection.notifyObserver("focusFallbackAfterDelete", {}) } findNearestItem(sortedIndex) { const $items = this._collection.$itemBySortedIndex; for (let index = sortedIndex; index >= 0; index -= 1) { const $item = null === $items || void 0 === $items ? void 0 : $items[index]; if (null !== $item && void 0 !== $item && $item.length) { return $item } } return } escHandler() { if (!this._collection.isResizing) { return } this._collection.moveAppointmentBack(); const resizableInstance = this.$focusTarget().dxResizable("instance"); if (resizableInstance) { resizableInstance._detachEventHandlers(); resizableInstance._attachEventHandlers(); resizableInstance._toggleResizingClass(false) } } tabHandler(e) { const items = this._collection.sortedItems; const nextIndex = this.focusedItemSortIndex + (e.shiftKey ? -1 : 1); const nextItemData = items[nextIndex]; if (!nextItemData) { return } e.preventDefault(); this.focusByItemData(nextItemData) } homeHandler(e) { const items = this._collection.sortedItems; const nextItemData = items[0]; if (!nextItemData) { return } e.preventDefault(); this.focusByItemData(nextItemData) } endHandler(e) { const items = this._collection.sortedItems; const nextItemData = items[items.length - 1]; if (!nextItemData) { return } e.preventDefault(); this.focusByItemData(nextItemData) } focusByItemData(itemData) { this.focusedItemSortIndex = itemData.sortedIndex; if (this._collection.isVirtualScrolling) { this.isNavigating = true; this.scrollToByItemData(itemData) } this.focus() } scrollToByItemData(itemData) { const date = new Date(Math.max(this._collection.invoke("getStartViewDate").getTime(), itemData.source.startDate)); const group = (0, _appointment_groups_utils.getRawAppointmentGroupValues)(itemData.itemData, this._collection.getResourceManager().resources); this._collection.option("scrollTo")(date, { group: group, allDay: itemData.allDay }) } getFirstVisibleItem() { const $items = this._collection.$itemBySortedIndex; const $itemsPlainArray = Object.values($items); const $firstItem = this._collection.isVirtualScrolling ? $itemsPlainArray.find($item => this.isItemVisibleInViewport($item)) ?? (0, _renderer.default)() : (0, _renderer.default)($itemsPlainArray[0]); return $firstItem } isItemVisibleInViewport($item) { const $container = this._collection.$element().closest(".dx-scrollable-container"); const containerRect = $container.get(0).getBoundingClientRect(); const itemRect = $item.get(0).getBoundingClientRect(); return itemRect.top < containerRect.bottom && itemRect.bottom > containerRect.top && itemRect.left < containerRect.right && itemRect.right > containerRect.left } } exports.AppointmentsKeyboardNavigation = AppointmentsKeyboardNavigation;