UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

433 lines (379 loc) • 14.3 kB
"use strict"; var $ = require("../core/renderer"), support = require("../core/utils/support"), extend = require("../core/utils/extend").extend, devices = require("../core/devices"), registerComponent = require("../core/component_registrator"), MultiView = require("./multi_view"), Tabs = require("./tabs"), iconUtils = require("../core/utils/icon"), getPublicElement = require("../core/utils/dom").getPublicElement, BindableTemplate = require("./widget/bindable_template"), windowUtils = require("../core/utils/window"); var TABPANEL_CLASS = "dx-tabpanel", TABPANEL_TABS_CLASS = "dx-tabpanel-tabs", TABPANEL_CONTAINER_CLASS = "dx-tabpanel-container", TABS_ITEM_TEXT_CLASS = "dx-tab-text"; /** * @name dxTabPanel * @publicName dxTabPanel * @inherits dxMultiView * @module ui/tab_panel * @export default */ var TabPanel = MultiView.inherit({ _getDefaultOptions: function _getDefaultOptions() { return extend(this.callBase(), { /** * @name dxTabPanelOptions.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 dxTabPanelOptions.hoverStateEnabled * @publicName hoverStateEnabled * @type boolean * @default true * @inheritdoc */ hoverStateEnabled: true, /** * @name dxTabPanelOptions.showNavButtons * @publicName showNavButtons * @type boolean * @default false */ showNavButtons: false, /** * @name dxTabPanelOptions.scrollByContent * @publicName scrollByContent * @type boolean * @default true */ scrollByContent: true, /** * @name dxTabPanelOptions.scrollingEnabled * @publicName scrollingEnabled * @type boolean * @default true */ scrollingEnabled: true, /** * @name dxTabPanelOptions.onTitleClick * @publicName onTitleClick * @extends Action * @type function(e)|string * @type_function_param1 e:object * @type_function_param1_field4 itemData:object * @type_function_param1_field5 itemElement:dxElement * @action */ onTitleClick: null, /** * @name dxTabPanelOptions.onTitleHold * @publicName onTitleHold * @extends Action * @type function(e) * @type_function_param1 e:object * @type_function_param1_field4 itemData:object * @type_function_param1_field5 itemElement:dxElement * @action */ onTitleHold: null, /** * @name dxTabPanelOptions.onTitleRendered * @publicName onTitleRendered * @extends Action * @type function(e) * @type_function_param1 e:object * @type_function_param1_field4 itemData:object * @type_function_param1_field5 itemElement:dxElement * @action */ onTitleRendered: null /** * @name dxTabPanelItemTemplate * @publicName dxTabPanelItemTemplate * @inherits dxMultiViewItemTemplate * @type object */ /** * @name dxTabPanelItemTemplate.tabtemplate * @publicName tabTemplate * @type template|function * @type_function_return string|Node|jQuery */ /** * @name dxTabPanelItemTemplate.visible * @publicName visible * @hidden * @inheritdoc */ /** * @name dxTabPanelItemTemplate.title * @publicName title * @type String */ /** * @name dxTabPanelItemTemplate.icon * @publicName icon * @type String */ /** * @name dxTabPanelItemTemplate.badge * @publicName badge * @type String */ }); }, _defaultOptionsRules: function _defaultOptionsRules() { return this.callBase().concat([{ device: function device() { return devices.real().deviceType === "desktop" && !devices.isSimulator(); }, options: { /** * @name dxTabPanelOptions.focusStateEnabled * @publicName focusStateEnabled * @type boolean * @default true @for desktop * @inheritdoc */ focusStateEnabled: true } }, { device: function device() { return !support.touch; }, options: { /** * @name dxTabPanelOptions.swipeEnabled * @publicName swipeEnabled * @type boolean * @default false @for non-touch_devices * @inheritdoc */ swipeEnabled: false } }, { device: { platform: "generic" }, options: { /** * @name dxTabPanelOptions.animationEnabled * @publicName animationEnabled * @type boolean * @default false * @default true @for Android|iOS|Windows_Mobile * @inheritdoc */ animationEnabled: false } }]); }, _init: function _init() { this.callBase(); this.$element().addClass(TABPANEL_CLASS); this.setAria("role", "tabpanel"); }, _initMarkup: function _initMarkup() { this.callBase(); this._createTitleActions(); this._renderLayout(); }, _initTemplates: function _initTemplates() { this.callBase(); this._defaultTemplates["title"] = new BindableTemplate(function ($container, data) { $container.text(data.title || String(data)); var $iconElement = iconUtils.getImageContainer(data.icon); $container.wrapInner($("<span>").addClass(TABS_ITEM_TEXT_CLASS)); $iconElement && $iconElement.prependTo($container); }, ["title", "html", "icon"], this.option("integrationOptions.watchMethod")); }, _createTitleActions: function _createTitleActions() { this._createTitleClickAction(); this._createTitleHoldAction(); this._createTitleRenderedAction(); }, _createTitleClickAction: function _createTitleClickAction() { this._titleClickAction = this._createActionByOption("onTitleClick"); }, _createTitleHoldAction: function _createTitleHoldAction() { this._titleHoldAction = this._createActionByOption("onTitleHold"); }, _createTitleRenderedAction: function _createTitleRenderedAction() { this._titleRenderedAction = this._createActionByOption("onTitleRendered"); }, _renderContent: function _renderContent() { var that = this; this.callBase(); if (this.option("templatesRenderAsynchronously")) { this._resizeEventTimer = setTimeout(function () { that._updateLayout(); }, 0); } }, _renderLayout: function _renderLayout() { if (this._tabs) { return; } var $element = this.$element(); this._$tabContainer = $("<div>").addClass(TABPANEL_TABS_CLASS).appendTo($element); var $tabs = $("<div>").appendTo(this._$tabContainer); this._tabs = this._createComponent($tabs, Tabs, this._tabConfig()); this._$container = $("<div>").addClass(TABPANEL_CONTAINER_CLASS).appendTo($element); this._$container.append(this._$wrapper); this._updateLayout(); }, _updateLayout: function _updateLayout() { if (windowUtils.hasWindow()) { var tabsHeight = this._$tabContainer.outerHeight(); this._$container.css({ "marginTop": -tabsHeight, "paddingTop": tabsHeight }); } }, _refreshActiveDescendant: function _refreshActiveDescendant() { if (!this._tabs) { return; } var tabs = this._tabs, tabItems = tabs.itemElements(), $activeTab = $(tabItems[tabs.option("selectedIndex")]), id = this.getFocusedItemId(); this.setAria("controls", undefined, $(tabItems)); this.setAria("controls", id, $activeTab); }, _tabConfig: function _tabConfig() { return { selectOnFocus: true, focusStateEnabled: this.option("focusStateEnabled"), hoverStateEnabled: this.option("hoverStateEnabled"), tabIndex: this.option("tabIndex"), selectedIndex: this.option("selectedIndex"), onItemClick: this._titleClickAction.bind(this), onItemHold: this._titleHoldAction.bind(this), itemHoldTimeout: this.option("itemHoldTimeout"), onSelectionChanged: function (e) { this.option("selectedIndex", e.component.option("selectedIndex")); this._refreshActiveDescendant(); }.bind(this), onItemRendered: this._titleRenderedAction.bind(this), itemTemplate: this._getTemplateByOption("itemTitleTemplate"), items: this.option("items"), noDataText: null, scrollingEnabled: this.option("scrollingEnabled"), scrollByContent: this.option("scrollByContent"), showNavButtons: this.option("showNavButtons"), itemTemplateProperty: "tabTemplate", loopItemFocus: this.option("loop"), selectionRequired: true, onOptionChanged: function (args) { if (args.name === "focusedElement") { if (args.value) { var $value = $(args.value); var $newItem = this._itemElements().eq($value.index()); this.option("focusedElement", getPublicElement($newItem)); } else { this.option("focusedElement", args.value); } } }.bind(this), onFocusIn: function (args) { this._focusInHandler(args.event); }.bind(this), onFocusOut: function (args) { this._focusOutHandler(args.event); }.bind(this) }; }, _renderFocusTarget: function _renderFocusTarget() { this._focusTarget().attr("tabIndex", -1); this._refreshActiveDescendant(); }, _updateFocusState: function _updateFocusState(e, isFocused) { this.callBase(e, isFocused); if (e.target === this._tabs._focusTarget().get(0)) { this._toggleFocusClass(isFocused, this._focusTarget()); } }, _setTabsOption: function _setTabsOption(name, value) { if (this._tabs) { this._tabs.option(name, value); } }, _visibilityChanged: function _visibilityChanged(visible) { if (visible) { this._tabs._dimensionChanged(); this._updateLayout(); } }, _optionChanged: function _optionChanged(args) { var name = args.name, value = args.value, fullName = args.fullName; switch (name) { case "dataSource": this.callBase(args); break; case "items": this._setTabsOption(fullName, value); this._updateLayout(); this._tabs.repaint(); this.callBase(args); break; case "selectedIndex": case "selectedItem": case "itemHoldTimeout": case "focusStateEnabled": case "hoverStateEnabled": this._setTabsOption(fullName, value); this.callBase(args); break; case "scrollingEnabled": case "scrollByContent": case "showNavButtons": this._setTabsOption(fullName, value); break; case "focusedElement": var id = value ? $(value).index() : value; var newItem = value ? this._tabs._itemElements().eq(id) : value; this._setTabsOption("focusedElement", getPublicElement(newItem)); this.callBase(args); this._tabs.focus(); break; case "itemTitleTemplate": this._setTabsOption("itemTemplate", this._getTemplateByOption("itemTitleTemplate")); break; case "onTitleClick": this._createTitleClickAction(); this._setTabsOption("onItemClick", this._titleClickAction.bind(this)); break; case "onTitleHold": this._createTitleHoldAction(); this._setTabsOption("onItemHold", this._titleHoldAction.bind(this)); break; case "onTitleRendered": this._createTitleRenderedAction(); this._setTabsOption("onItemRendered", this._titleRenderedAction.bind(this)); break; case "loop": this._setTabsOption("loopItemFocus", value); break; default: this.callBase(args); } }, _clean: function _clean() { clearTimeout(this._resizeEventTimer); this.callBase(); } }); registerComponent("dxTabPanel", TabPanel); module.exports = TabPanel;