UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

308 lines (305 loc) • 12 kB
/** * DevExtreme (cjs/__internal/ui/date_box/m_date_view_roller.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 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.default = void 0; var _animation = require("../../../common/core/animation"); var _translator = require("../../../common/core/animation/translator"); var _click = require("../../../common/core/events/click"); var _events_engine = _interopRequireDefault(require("../../../common/core/events/core/events_engine")); var _index = require("../../../common/core/events/utils/index"); var _component_registrator = _interopRequireDefault(require("../../../core/component_registrator")); var _devices = _interopRequireDefault(require("../../../core/devices")); var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _iterator = require("../../../core/utils/iterator"); var _size = require("../../../core/utils/size"); var _convert_location = require("../../ui/scroll_view/utils/convert_location"); var _m_scrollable = _interopRequireDefault(require("../scroll_view/m_scrollable")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function(n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]) } } return n }, _extends.apply(null, arguments) } const DATEVIEW_ROLLER_CLASS = "dx-dateviewroller"; const DATEVIEW_ROLLER_ACTIVE_CLASS = "dx-state-active"; const DATEVIEW_ROLLER_CURRENT_CLASS = "dx-dateviewroller-current"; const DATEVIEW_ROLLER_ITEM_CLASS = "dx-dateview-item"; const DATEVIEW_ROLLER_ITEM_SELECTED_CLASS = "dx-dateview-item-selected"; const DATEVIEW_ROLLER_ITEM_SELECTED_FRAME_CLASS = "dx-dateview-item-selected-frame"; const DATEVIEW_ROLLER_ITEM_SELECTED_BORDER_CLASS = "dx-dateview-item-selected-border"; class DateViewRoller extends _m_scrollable.default { _getDefaultOptions() { return _extends({}, super._getDefaultOptions(), { showScrollbar: "never", useNative: false, selectedIndex: 0, bounceEnabled: false, items: [], showOnClick: false, onClick: null, onSelectedIndexChanged: null, scrollByContent: true }) } _init() { super._init(); this.option("onVisibilityChange", this._visibilityChangedHandler.bind(this)); this.option("onEnd", this._endActionHandler.bind(this)) } _render() { super._render(); this._renderSelectedItemFrame(); this.$element().addClass("dx-dateviewroller"); this._renderContainerClick(); this._renderItems(); this._renderSelectedValue(); this._renderItemsClick(); this._renderWheelEvent(); this._renderSelectedIndexChanged() } _renderSelectedIndexChanged() { this._selectedIndexChanged = this._createActionByOption("onSelectedIndexChanged") } _renderWheelEvent() { _events_engine.default.on((0, _renderer.default)(this.container()), "dxmousewheel", (e => { this._isWheelScrolled = true })) } _renderContainerClick() { if (!this.option("showOnClick")) { return } const eventName = (0, _index.addNamespace)(_click.name, this.NAME); const clickAction = this._createActionByOption("onClick"); _events_engine.default.off((0, _renderer.default)(this.container()), eventName); _events_engine.default.on((0, _renderer.default)(this.container()), eventName, (e => { clickAction({ event: e }) })) } _renderItems() { const items = this.option("items") || []; let $items = (0, _renderer.default)(); (0, _renderer.default)(this.content()).empty(); items.forEach((item => { $items = $items.add((0, _renderer.default)("<div>").addClass("dx-dateview-item").append(item)) })); (0, _renderer.default)(this.content()).append($items); this._$items = $items; this.update() } _renderSelectedItemFrame() { (0, _renderer.default)("<div>").addClass("dx-dateview-item-selected-frame").append((0, _renderer.default)("<div>").addClass("dx-dateview-item-selected-border")).appendTo((0, _renderer.default)(this.container())) } _renderSelectedValue(selectedIndex) { const index = this._fitIndex(selectedIndex ?? this.option("selectedIndex")); this._moveTo({ top: this._getItemPosition(index) }); this._renderActiveStateItem() } _fitIndex(index) { const items = this.option("items") || []; const itemCount = items.length; if (index >= itemCount) { return itemCount - 1 } if (index < 0) { return 0 } return index } _getItemPosition(index) { return Math.round(this._itemHeight() * index) } _renderItemsClick() { const itemSelector = this._getItemSelector(); const eventName = (0, _index.addNamespace)(_click.name, this.NAME); _events_engine.default.off(this.$element(), eventName, itemSelector); _events_engine.default.on(this.$element(), eventName, itemSelector, this._itemClickHandler.bind(this)) } _getItemSelector() { return ".dx-dateview-item" } _itemClickHandler(e) { this.option("selectedIndex", this._itemElementIndex(e.currentTarget)) } _itemElementIndex(itemElement) { return this._itemElements().index(itemElement) } _itemElements() { return this.$element().find(this._getItemSelector()) } _renderActiveStateItem() { const selectedIndex = this.option("selectedIndex"); (0, _iterator.each)(this._$items, (function(index) { (0, _renderer.default)(this).toggleClass("dx-dateview-item-selected", selectedIndex === index) })) } _shouldScrollToNeighborItem() { return "desktop" === _devices.default.real().deviceType && this._isWheelScrolled } _moveTo(targetLocation) { const { top: top, left: left } = (0, _convert_location.convertToLocation)(targetLocation); const location = this.scrollOffset(); const delta = { x: location.left - left, y: location.top - top }; if (this._isVisible() && (delta.x || delta.y)) { this._prepareDirections(true); if (this._animation && !this._shouldScrollToNeighborItem()) { const that = this; _animation.fx.stop((0, _renderer.default)(this.content())); _animation.fx.animate((0, _renderer.default)(this.content()), { duration: 200, type: "slide", to: { top: Math.floor(delta.y) }, complete() { (0, _translator.resetPosition)((0, _renderer.default)(that.content())); that.handleMove({ delta: delta }) } }); delete this._animation } else { this.handleMove({ delta: delta }) } } } _validate(e) { return this._moveIsAllowed(e) } _fitSelectedIndexInRange(index) { const itemsCount = this.option("items").length; return Math.max(Math.min(index, itemsCount - 1), 0) } _isInNullNeighborhood(x) { return -.1 <= x && x <= .1 } _getSelectedIndexAfterScroll(currentSelectedIndex) { const locationTop = this.scrollOffset().top; const currentSelectedIndexPosition = currentSelectedIndex * this._itemHeight(); const dy = locationTop - currentSelectedIndexPosition; if (this._isInNullNeighborhood(dy)) { return currentSelectedIndex } const direction = dy > 0 ? 1 : -1; const newSelectedIndex = this._fitSelectedIndexInRange(currentSelectedIndex + direction); return newSelectedIndex } _getNewSelectedIndex(currentSelectedIndex) { if (this._shouldScrollToNeighborItem()) { return this._getSelectedIndexAfterScroll(currentSelectedIndex) } this._animation = true; const ratio = this.scrollOffset().top / this._itemHeight(); return Math.round(ratio) } _endActionHandler() { const currentSelectedIndex = this.option("selectedIndex"); const newSelectedIndex = this._getNewSelectedIndex(currentSelectedIndex); if (newSelectedIndex === currentSelectedIndex) { this._renderSelectedValue(newSelectedIndex) } else { this.option("selectedIndex", newSelectedIndex) } this._isWheelScrolled = false } _itemHeight() { const $item = this._$items.first(); return (0, _size.getHeight)($item) } _toggleActive(state) { this.$element().toggleClass("dx-state-active", state) } _isVisible() { return (0, _renderer.default)(this.container()).is(":visible") } _fireSelectedIndexChanged(value, previousValue) { var _this$_selectedIndexC; null === (_this$_selectedIndexC = this._selectedIndexChanged) || void 0 === _this$_selectedIndexC || _this$_selectedIndexC.call(this, { value: value, previousValue: previousValue, event: void 0 }) } _visibilityChanged(visible) { super._visibilityChanged(visible); this._visibilityChangedHandler(visible) } _visibilityChangedHandler(visible) { if (visible) { this._visibilityTimer = setTimeout((() => { this._renderSelectedValue(this.option("selectedIndex")) })) } this.toggleActiveState(false) } toggleActiveState(state) { this.$element().toggleClass("dx-dateviewroller-current", state) } _refreshSelectedIndex() { const selectedIndex = this.option("selectedIndex"); const fitIndex = this._fitIndex(selectedIndex); if (fitIndex === selectedIndex) { this._renderActiveStateItem() } else { this.option("selectedIndex", fitIndex) } } _optionChanged(args) { switch (args.name) { case "selectedIndex": this._fireSelectedIndexChanged(args.value, args.previousValue); this._renderSelectedValue(args.value); break; case "items": this._renderItems(); this._refreshSelectedIndex(); break; case "onClick": case "showOnClick": this._renderContainerClick(); break; case "onSelectedIndexChanged": this._renderSelectedIndexChanged(); break; default: super._optionChanged(args) } } _dispose() { clearTimeout(this._visibilityTimer); super._dispose() } }(0, _component_registrator.default)("dxDateViewRoller", DateViewRoller); var _default = exports.default = DateViewRoller;