tab_panel.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /**
  2. * DevExtreme (ui/tab_panel.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var _renderer = require("../core/renderer");
  11. var _renderer2 = _interopRequireDefault(_renderer);
  12. var _support = require("../core/utils/support");
  13. var _support2 = _interopRequireDefault(_support);
  14. var _extend = require("../core/utils/extend");
  15. var _devices = require("../core/devices");
  16. var _devices2 = _interopRequireDefault(_devices);
  17. var _component_registrator = require("../core/component_registrator");
  18. var _component_registrator2 = _interopRequireDefault(_component_registrator);
  19. var _multi_view = require("./multi_view");
  20. var _multi_view2 = _interopRequireDefault(_multi_view);
  21. var _tabs = require("./tabs");
  22. var _tabs2 = _interopRequireDefault(_tabs);
  23. var _item = require("./tab_panel/item");
  24. var _item2 = _interopRequireDefault(_item);
  25. var _icon = require("../core/utils/icon");
  26. var _dom = require("../core/utils/dom");
  27. var _bindable_template = require("./widget/bindable_template");
  28. var _bindable_template2 = _interopRequireDefault(_bindable_template);
  29. var _type = require("../core/utils/type");
  30. var _window = require("../core/utils/window");
  31. var _window2 = _interopRequireDefault(_window);
  32. function _interopRequireDefault(obj) {
  33. return obj && obj.__esModule ? obj : {
  34. "default": obj
  35. }
  36. }
  37. var TABPANEL_CLASS = "dx-tabpanel";
  38. var TABPANEL_TABS_CLASS = "dx-tabpanel-tabs";
  39. var TABPANEL_CONTAINER_CLASS = "dx-tabpanel-container";
  40. var TABS_ITEM_TEXT_CLASS = "dx-tab-text";
  41. var TabPanel = _multi_view2.default.inherit({
  42. _getDefaultOptions: function() {
  43. return (0, _extend.extend)(this.callBase(), {
  44. itemTitleTemplate: "title",
  45. hoverStateEnabled: true,
  46. showNavButtons: false,
  47. scrollByContent: true,
  48. scrollingEnabled: true,
  49. onTitleClick: null,
  50. onTitleHold: null,
  51. onTitleRendered: null,
  52. badgeExpr: function(data) {
  53. return data ? data.badge : void 0
  54. }
  55. })
  56. },
  57. _defaultOptionsRules: function() {
  58. return this.callBase().concat([{
  59. device: function() {
  60. return "desktop" === _devices2.default.real().deviceType && !_devices2.default.isSimulator()
  61. },
  62. options: {
  63. focusStateEnabled: true
  64. }
  65. }, {
  66. device: function() {
  67. return !_support2.default.touch
  68. },
  69. options: {
  70. swipeEnabled: false
  71. }
  72. }, {
  73. device: {
  74. platform: "generic"
  75. },
  76. options: {
  77. animationEnabled: false
  78. }
  79. }])
  80. },
  81. _init: function() {
  82. this.callBase();
  83. this.$element().addClass(TABPANEL_CLASS);
  84. this.setAria("role", "tabpanel")
  85. },
  86. _initMarkup: function() {
  87. this.callBase();
  88. this._createTitleActions();
  89. this._renderLayout()
  90. },
  91. _initTemplates: function() {
  92. this.callBase();
  93. this._defaultTemplates.title = new _bindable_template2.default(function($container, data) {
  94. if ((0, _type.isPlainObject)(data)) {
  95. if ((0, _type.isDefined)(data.title) && !(0, _type.isPlainObject)(data.title)) {
  96. $container.text(data.title)
  97. }
  98. var $iconElement = (0, _icon.getImageContainer)(data.icon);
  99. $iconElement && $iconElement.prependTo($container)
  100. } else {
  101. if ((0, _type.isDefined)(data)) {
  102. $container.text(String(data))
  103. }
  104. }
  105. $container.wrapInner((0, _renderer2.default)("<span>").addClass(TABS_ITEM_TEXT_CLASS))
  106. }, ["title", "icon"], this.option("integrationOptions.watchMethod"))
  107. },
  108. _createTitleActions: function() {
  109. this._createTitleClickAction();
  110. this._createTitleHoldAction();
  111. this._createTitleRenderedAction()
  112. },
  113. _createTitleClickAction: function() {
  114. this._titleClickAction = this._createActionByOption("onTitleClick")
  115. },
  116. _createTitleHoldAction: function() {
  117. this._titleHoldAction = this._createActionByOption("onTitleHold")
  118. },
  119. _createTitleRenderedAction: function() {
  120. this._titleRenderedAction = this._createActionByOption("onTitleRendered")
  121. },
  122. _renderContent: function() {
  123. var that = this;
  124. this.callBase();
  125. if (this.option("templatesRenderAsynchronously")) {
  126. this._resizeEventTimer = setTimeout(function() {
  127. that._updateLayout()
  128. }, 0)
  129. }
  130. },
  131. _renderLayout: function() {
  132. if (this._tabs) {
  133. return
  134. }
  135. var $element = this.$element();
  136. this._$tabContainer = (0, _renderer2.default)("<div>").addClass(TABPANEL_TABS_CLASS).appendTo($element);
  137. var $tabs = (0, _renderer2.default)("<div>").appendTo(this._$tabContainer);
  138. this._tabs = this._createComponent($tabs, _tabs2.default, this._tabConfig());
  139. this._$container = (0, _renderer2.default)("<div>").addClass(TABPANEL_CONTAINER_CLASS).appendTo($element);
  140. this._$container.append(this._$wrapper);
  141. this._updateLayout()
  142. },
  143. _updateLayout: function() {
  144. if (_window2.default.hasWindow()) {
  145. var tabsHeight = this._$tabContainer.outerHeight();
  146. this._$container.css({
  147. marginTop: -tabsHeight,
  148. paddingTop: tabsHeight
  149. })
  150. }
  151. },
  152. _refreshActiveDescendant: function() {
  153. if (!this._tabs) {
  154. return
  155. }
  156. var tabs = this._tabs;
  157. var tabItems = tabs.itemElements();
  158. var $activeTab = (0, _renderer2.default)(tabItems[tabs.option("selectedIndex")]);
  159. var id = this.getFocusedItemId();
  160. this.setAria("controls", void 0, (0, _renderer2.default)(tabItems));
  161. this.setAria("controls", id, $activeTab)
  162. },
  163. _tabConfig: function() {
  164. return {
  165. selectOnFocus: true,
  166. focusStateEnabled: this.option("focusStateEnabled"),
  167. hoverStateEnabled: this.option("hoverStateEnabled"),
  168. repaintChangesOnly: this.option("repaintChangesOnly"),
  169. tabIndex: this.option("tabIndex"),
  170. selectedIndex: this.option("selectedIndex"),
  171. badgeExpr: this.option("badgeExpr"),
  172. onItemClick: this._titleClickAction.bind(this),
  173. onItemHold: this._titleHoldAction.bind(this),
  174. itemHoldTimeout: this.option("itemHoldTimeout"),
  175. onSelectionChanged: function(e) {
  176. this.option("selectedIndex", e.component.option("selectedIndex"));
  177. this._refreshActiveDescendant()
  178. }.bind(this),
  179. onItemRendered: this._titleRenderedAction.bind(this),
  180. itemTemplate: this._getTemplateByOption("itemTitleTemplate"),
  181. items: this.option("items"),
  182. noDataText: null,
  183. scrollingEnabled: this.option("scrollingEnabled"),
  184. scrollByContent: this.option("scrollByContent"),
  185. showNavButtons: this.option("showNavButtons"),
  186. itemTemplateProperty: "tabTemplate",
  187. loopItemFocus: this.option("loop"),
  188. selectionRequired: true,
  189. onOptionChanged: function(args) {
  190. if ("focusedElement" === args.name) {
  191. if (args.value) {
  192. var $value = (0, _renderer2.default)(args.value);
  193. var $newItem = this._itemElements().eq($value.index());
  194. this.option("focusedElement", (0, _dom.getPublicElement)($newItem))
  195. } else {
  196. this.option("focusedElement", args.value)
  197. }
  198. }
  199. }.bind(this),
  200. onFocusIn: function(args) {
  201. this._focusInHandler(args.event)
  202. }.bind(this),
  203. onFocusOut: function(args) {
  204. if (!this._isFocusOutHandlerExecuting) {
  205. this._focusOutHandler(args.event)
  206. }
  207. }.bind(this)
  208. }
  209. },
  210. _renderFocusTarget: function() {
  211. this._focusTarget().attr("tabIndex", -1)
  212. },
  213. _updateFocusState: function(e, isFocused) {
  214. this.callBase(e, isFocused);
  215. if (e.target === this._tabs._focusTarget().get(0)) {
  216. this._toggleFocusClass(isFocused, this._focusTarget())
  217. }
  218. },
  219. _focusOutHandler: function(e) {
  220. this._isFocusOutHandlerExecuting = true;
  221. this.callBase.apply(this, arguments);
  222. this._tabs._focusOutHandler(e);
  223. this._isFocusOutHandlerExecuting = false
  224. },
  225. _setTabsOption: function(name, value) {
  226. if (this._tabs) {
  227. this._tabs.option(name, value)
  228. }
  229. },
  230. _visibilityChanged: function(visible) {
  231. if (visible) {
  232. this._tabs._dimensionChanged();
  233. this._updateLayout()
  234. }
  235. },
  236. registerKeyHandler: function(key, handler) {
  237. this.callBase(key, handler);
  238. if (this._tabs) {
  239. this._tabs.registerKeyHandler(key, handler)
  240. }
  241. },
  242. repaint: function() {
  243. this.callBase();
  244. this._tabs.repaint()
  245. },
  246. _optionChanged: function(args) {
  247. var name = args.name;
  248. var value = args.value;
  249. var fullName = args.fullName;
  250. switch (name) {
  251. case "dataSource":
  252. this.callBase(args);
  253. break;
  254. case "items":
  255. this._setTabsOption(name, this.option(name));
  256. this._updateLayout();
  257. if (!this.option("repaintChangesOnly")) {
  258. this._tabs.repaint()
  259. }
  260. this.callBase(args);
  261. break;
  262. case "width":
  263. this.callBase(args);
  264. this._tabs.repaint();
  265. break;
  266. case "selectedIndex":
  267. case "selectedItem":
  268. case "itemHoldTimeout":
  269. case "focusStateEnabled":
  270. case "hoverStateEnabled":
  271. this._setTabsOption(fullName, value);
  272. this.callBase(args);
  273. break;
  274. case "scrollingEnabled":
  275. case "scrollByContent":
  276. case "showNavButtons":
  277. this._setTabsOption(fullName, value);
  278. break;
  279. case "focusedElement":
  280. var id = value ? (0, _renderer2.default)(value).index() : value;
  281. var newItem = value ? this._tabs._itemElements().eq(id) : value;
  282. this._setTabsOption("focusedElement", (0, _dom.getPublicElement)(newItem));
  283. this.callBase(args);
  284. break;
  285. case "itemTitleTemplate":
  286. this._setTabsOption("itemTemplate", this._getTemplateByOption("itemTitleTemplate"));
  287. break;
  288. case "onTitleClick":
  289. this._createTitleClickAction();
  290. this._setTabsOption("onItemClick", this._titleClickAction.bind(this));
  291. break;
  292. case "onTitleHold":
  293. this._createTitleHoldAction();
  294. this._setTabsOption("onItemHold", this._titleHoldAction.bind(this));
  295. break;
  296. case "onTitleRendered":
  297. this._createTitleRenderedAction();
  298. this._setTabsOption("onItemRendered", this._titleRenderedAction.bind(this));
  299. break;
  300. case "loop":
  301. this._setTabsOption("loopItemFocus", value);
  302. break;
  303. case "badgeExpr":
  304. this._invalidate();
  305. break;
  306. default:
  307. this.callBase(args)
  308. }
  309. },
  310. _clean: function() {
  311. clearTimeout(this._resizeEventTimer);
  312. this.callBase()
  313. }
  314. });
  315. TabPanel.ItemClass = _item2.default;
  316. (0, _component_registrator2.default)("dxTabPanel", TabPanel);
  317. module.exports = TabPanel;
  318. module.exports.default = module.exports;