UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

564 lines (460 loc) • 16.7 kB
"use strict"; var $ = require("../core/renderer"), eventsEngine = require("../events/core/events_engine"), fx = require("../animation/fx"), swipeEvents = require("../events/swipe"), translator = require("../animation/translator"), domUtils = require("../core/utils/dom"), extend = require("../core/utils/extend").extend, isDefined = require("../core/utils/type").isDefined, registerComponent = require("../core/component_registrator"), eventUtils = require("../events/utils"), config = require("../core/config"), CollectionWidget = require("./collection/ui.collection_widget.edit"), PivotTabs = require("./pivot/ui.pivot_tabs"), EmptyTemplate = require("./widget/empty_template"), ChildDefaultTemplate = require("./widget/child_default_template"), Deferred = require("../core/utils/deferred").Deferred; var PIVOT_CLASS = "dx-pivot", PIVOT_AUTOHEIGHT_CLASS = "dx-pivot-autoheight", PIVOT_WRAPPER_CLASS = "dx-pivot-wrapper", PIVOT_TABS_CONTAINER_CLASS = "dx-pivottabs-container", PIVOT_ITEM_CONTAINER_CLASS = "dx-pivot-itemcontainer", PIVOT_ITEM_WRAPPER_CLASS = "dx-pivot-itemwrapper", PIVOT_ITEM_CLASS = "dx-pivot-item", PIVOT_ITEM_HIDDEN_CLASS = "dx-pivot-item-hidden", PIVOT_ITEM_DATA_KEY = "dxPivotItemData", PIVOT_RETURN_BACK_DURATION = 200, PIVOT_SLIDE_AWAY_DURATION = 50, PIVOT_SLIDE_BACK_DURATION = 250, PIVOT_SLIDE_BACK_EASING = "cubic-bezier(.10, 1, 0, 1)"; var animation = { returnBack: function returnBack($element) { fx.animate($element, { type: "slide", to: { left: 0 }, duration: PIVOT_RETURN_BACK_DURATION }); }, slideAway: function slideAway($element, position, complete) { fx.animate($element, { type: "slide", to: { left: position }, duration: PIVOT_SLIDE_AWAY_DURATION, complete: complete }); }, slideBack: function slideBack($element) { fx.animate($element, { type: "slide", to: { left: 0 }, easing: PIVOT_SLIDE_BACK_EASING, duration: PIVOT_SLIDE_BACK_DURATION }); }, complete: function complete($element) { fx.stop($element, true); } }; /** * @name dxPivot * @publicName dxPivot * @inherits CollectionWidget * @module ui/pivot * @export default * @deprecated */ var Pivot = CollectionWidget.inherit({ _getDefaultOptions: function _getDefaultOptions() { return extend(this.callBase(), { /** * @name dxPivotOptions.selectedIndex * @publicName selectedIndex * @type number * @default 0 */ selectedIndex: 0, /** * @name dxPivotOptions.swipeEnabled * @publicName swipeEnabled * @type boolean * @default true */ swipeEnabled: true, /** * @name dxPivotOptions.itemTitleTemplate * @publicName itemTitleTemplate * @type template|function * @default "title" * @type_function_param1 itemData:object * @type_function_param2 itemIndex:number * @type_function_param3 itemElement:dxElement * @type_function_return string|Node|jQuery */ itemTitleTemplate: "title", /** * @name dxPivotOptions.contentTemplate * @publicName contentTemplate * @type template|function * @default "content" * @type_function_param1 container:dxElement * @type_function_return string|Node|jQuery */ contentTemplate: "content", /** * @name dxPivotOptions.focusStateEnabled * @publicName focusStateEnabled * @type boolean * @default false * @hidden */ focusStateEnabled: false, selectionMode: "single", selectionRequired: true, selectionByClick: false /** * @name dxPivotOptions.noDataText * @publicName noDataText * @hidden * @inheritdoc */ /** * @name dxPivotOptions.selectedItems * @publicName selectedItems * @hidden * @inheritdoc */ /** * @name dxPivotOptions.selectedItemKeys * @publicName selectedItemKeys * @hidden * @inheritdoc */ /** * @name dxPivotOptions.keyExpr * @publicName keyExpr * @hidden * @inheritdoc */ /** * @name dxPivotOptions.accessKey * @publicName accessKey * @hidden * @inheritdoc */ /** * @name dxPivotOptions.tabIndex * @publicName tabIndex * @hidden * @inheritdoc */ }); }, _itemClass: function _itemClass() { return PIVOT_ITEM_CLASS; }, _itemDataKey: function _itemDataKey() { return PIVOT_ITEM_DATA_KEY; }, _itemContainer: function _itemContainer() { return this._$itemWrapper; }, _elementWidth: function _elementWidth() { if (!this._elementWidthCache) { this._elementWidthCache = this.$element().width(); } return this._elementWidthCache; }, _clearElementWidthCache: function _clearElementWidthCache() { delete this._elementWidthCache; }, _init: function _init() { this.callBase(); this.$element().addClass(PIVOT_CLASS); this._initWrapper(); this._initTabs(); this._initItemContainer(); this._clearItemsCache(); this._initSwipeHandlers(); }, _initTemplates: function _initTemplates() { this.callBase(); /** * @name dxPivotItemTemplate * @publicName dxPivotItemTemplate * @inherits CollectionWidgetItemTemplate * @type object */ /** * @name dxPivotItemTemplate.titleTemplate * @publicName titleTemplate * @type template|function * @type_function_return string|Node|jQuery */ /** * @name dxPivotItemTemplate.visible * @publicName visible * @hidden * @inheritdoc */ /** * @name dxPivotItemTemplate.title * @publicName title * @type String */ this._defaultTemplates["content"] = new EmptyTemplate(); this._defaultTemplates["title"] = new ChildDefaultTemplate("item", this); }, _dimensionChanged: function _dimensionChanged() { this._clearElementWidthCache(); }, _initWrapper: function _initWrapper() { this._$wrapper = $("<div>").addClass(PIVOT_WRAPPER_CLASS).appendTo(this.$element()); }, _initItemContainer: function _initItemContainer() { var $itemContainer = $("<div>").addClass(PIVOT_ITEM_CONTAINER_CLASS); this._$wrapper.append($itemContainer); this._$itemWrapper = $("<div>").addClass(PIVOT_ITEM_WRAPPER_CLASS); $itemContainer.append(this._$itemWrapper); }, _clearItemsCache: function _clearItemsCache() { this._itemsCache = []; }, _initTabs: function _initTabs() { var that = this, $tabsContainer = $("<div>").addClass(PIVOT_TABS_CONTAINER_CLASS); this._$wrapper.append($tabsContainer); this._tabs = this._createComponent($tabsContainer, PivotTabs, { itemTemplateProperty: "titleTemplate", itemTemplate: this._getTemplateByOption("itemTitleTemplate"), items: this.option("items"), selectedIndex: this.option("selectedIndex"), onPrepare: function onPrepare() { that._prepareAnimation(); }, onUpdatePosition: function onUpdatePosition(args) { that._updateContentPosition(args.offset); }, onRollback: function onRollback() { that._animateRollback(); }, onSelectionChanged: function onSelectionChanged(args) { that.option("selectedItem", args.addedItems[0]); }, swipeEnabled: this.option("swipeEnabled") }); }, _initMarkup: function _initMarkup() { this._renderContentTemplate(); this.callBase(); }, _render: function _render() { this.callBase(); var selectedIndex = this.option("selectedIndex"); this._renderCurrentContent(selectedIndex, selectedIndex); }, _renderContentTemplate: function _renderContentTemplate() { if (isDefined(this._singleContent)) { return; } this._getTemplateByOption("contentTemplate").render({ container: domUtils.getPublicElement(this._$itemWrapper) }); this._singleContent = !this._$itemWrapper.is(":empty"); }, _renderDimensions: function _renderDimensions() { this.callBase(); this.$element().toggleClass(PIVOT_AUTOHEIGHT_CLASS, this.option("height") === "auto"); }, _visibilityChanged: function _visibilityChanged(visible) { if (visible) { this._tabs._dimensionChanged(); } }, _renderCurrentContent: function _renderCurrentContent(currentIndex, previousIndex) { var itemsCache = this._itemsCache; itemsCache[previousIndex] = this._selectedItemElement(); var $hidingItem = itemsCache[previousIndex], $showingItem = itemsCache[currentIndex]; domUtils.triggerHidingEvent($hidingItem); $hidingItem.addClass(PIVOT_ITEM_HIDDEN_CLASS); if ($showingItem) { $showingItem.removeClass(PIVOT_ITEM_HIDDEN_CLASS); domUtils.triggerShownEvent($showingItem); } else { this._prepareContent(); this._renderContent(); } this._selectionChangePromise && this._selectionChangePromise.resolve(); this._selectionChangePromise = new Deferred(); }, _updateContentPosition: function _updateContentPosition(offset) { translator.move(this._$itemWrapper, { left: this._calculatePixelOffset(offset) }); }, _animateRollback: function _animateRollback() { animation.returnBack(this._$itemWrapper); }, _animateComplete: function _animateComplete(newIndex, currentIndex) { var $itemWrapper = this._$itemWrapper, rtlSignCorrection = this._getRTLSignCorrection(), intermediatePosition = this._elementWidth() * (this._isPrevSwipeHandled() ? 1 : -1) * rtlSignCorrection; animation.slideAway($itemWrapper, intermediatePosition, function () { translator.move($itemWrapper, { left: -intermediatePosition }); this._renderCurrentContent(newIndex, currentIndex); }.bind(this)); animation.slideBack($itemWrapper); }, _calculatePixelOffset: function _calculatePixelOffset(offset) { offset = offset || 0; return offset * this._elementWidth(); }, _isPrevSwipeHandled: function _isPrevSwipeHandled() { var wrapperOffset = translator.locate(this._$itemWrapper).left, rtl = this.option("rtlEnabled"); return rtl ^ wrapperOffset > 0 && wrapperOffset !== 0; }, _initSwipeHandlers: function _initSwipeHandlers() { var $element = this.$element(); eventsEngine.on($element, eventUtils.addNamespace(swipeEvents.start, this.NAME), { itemSizeFunc: this._elementWidth.bind(this) }, this._swipeStartHandler.bind(this)); eventsEngine.on($element, eventUtils.addNamespace(swipeEvents.swipe, this.NAME), this._swipeUpdateHandler.bind(this)); eventsEngine.on($element, eventUtils.addNamespace(swipeEvents.end, this.NAME), this._swipeEndHandler.bind(this)); }, _swipeStartHandler: function _swipeStartHandler(e) { this._prepareAnimation(); this._tabs.prepare(); if (config().designMode || this.option("disabled") || !this.option("swipeEnabled") || this._indexBoundary() <= 1) { e.cancel = true; } else { this._swipeGestureRunning = true; } e.maxLeftOffset = 1; e.maxRightOffset = 1; }, _prepareAnimation: function _prepareAnimation() { this._stopAnimation(); }, _stopAnimation: function _stopAnimation() { animation.complete(this._$itemWrapper); }, _swipeUpdateHandler: function _swipeUpdateHandler(e) { var offset = e.offset; this._updateContentPosition(offset); this._tabs.updatePosition(offset); }, _swipeEndHandler: function _swipeEndHandler(e) { var targetOffset = e.targetOffset * this._getRTLSignCorrection(); if (targetOffset === 0) { this._animateRollback(); this._tabs.rollback(); } else { var newIndex = this._normalizeIndex(this.option("selectedIndex") - targetOffset); this.option("selectedIndex", newIndex); } this._swipeGestureRunning = false; }, _normalizeIndex: function _normalizeIndex(index) { var boundary = this._indexBoundary(); if (index < 0) { index = boundary + index; } if (index >= boundary) { index = index - boundary; } return index; }, _indexBoundary: function _indexBoundary() { return this.option("items").length; }, _renderContentImpl: function _renderContentImpl() { if (this._singleContent) { return; } var items = this.option("items"), selectedIndex = this.option("selectedIndex"); if (items.length) { this._renderItems([items[selectedIndex]]); } }, _selectedItemElement: function _selectedItemElement() { return this._$itemWrapper.children("." + PIVOT_ITEM_CLASS + ":not(." + PIVOT_ITEM_HIDDEN_CLASS + ")"); }, _getRTLSignCorrection: function _getRTLSignCorrection() { return this.option("rtlEnabled") ? -1 : 1; }, _clean: function _clean() { animation.complete(this._$itemWrapper); this.callBase(); }, _cleanItemContainer: function _cleanItemContainer() { if (this._singleContent) { return; } this.callBase(); }, _refresh: function _refresh() { this._tabs._refresh(); this.callBase(); }, _updateSelection: function _updateSelection(addedItems, removedItems) { var newIndex = addedItems[0], oldIndex = removedItems[0]; if (!this._swipeGestureRunning) { this._prepareAnimation(); } this._animateComplete(newIndex, oldIndex); this._tabs.option("selectedIndex", newIndex); }, _optionChanged: function _optionChanged(args) { var value = args.value; switch (args.name) { case "disabled": this._tabs.option("disabled", value); this.callBase(args); break; case "items": this._tabs.option(args.fullName, value); this._clearItemsCache(); this.callBase(args); break; case "rtlEnabled": this._tabs.option("rtlEnabled", value); this._clearItemsCache(); this.callBase(args); break; case "itemTitleTemplate": this._tabs.option("itemTemplate", this._getTemplate(value)); break; case "swipeEnabled": this._tabs.option("swipeEnabled", value); break; case "contentTemplate": this._singleContent = null; this._invalidate(); break; default: this.callBase(args); } } /** * @name dxPivotMethods.registerKeyHandler * @publicName registerKeyHandler(key, handler) * @hidden * @inheritdoc */ /** * @name dxPivotMethods.focus * @publicName focus() * @hidden * @inheritdoc */ }); registerComponent("dxPivot", Pivot); module.exports = Pivot; ///#DEBUG module.exports.mockPivotTabs = function (Mock) { PivotTabs = Mock; }; module.exports.animation = animation; ///#ENDDEBUG