@syncfusion/ej2-navigations 20.1.47 → 20.1.51-10460

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. package/.eslintrc.json +243 -243
  2. package/CHANGELOG.md +1601 -1570
  3. package/README.md +194 -194
  4. package/dist/ej2-navigations.min.js +1 -0
  5. package/dist/ej2-navigations.umd.min.js +1 -10
  6. package/dist/ej2-navigations.umd.min.js.map +1 -1
  7. package/dist/es6/ej2-navigations.es2015.js +92 -80
  8. package/dist/es6/ej2-navigations.es2015.js.map +1 -1
  9. package/dist/es6/ej2-navigations.es5.js +251 -239
  10. package/dist/es6/ej2-navigations.es5.js.map +1 -1
  11. package/dist/global/ej2-navigations.min.js +1 -10
  12. package/dist/global/ej2-navigations.min.js.map +1 -1
  13. package/dist/global/index.d.ts +0 -9
  14. package/dist/ts/accordion/accordion.ts +1545 -0
  15. package/dist/ts/breadcrumb/breadcrumb.ts +873 -0
  16. package/dist/ts/carousel/carousel.ts +1181 -0
  17. package/dist/ts/common/h-scroll.ts +477 -0
  18. package/dist/ts/common/menu-base.ts +2357 -0
  19. package/dist/ts/common/menu-scroll.ts +105 -0
  20. package/dist/ts/common/v-scroll.ts +454 -0
  21. package/{src/context-menu/context-menu.d.ts → dist/ts/context-menu/context-menu.ts} +134 -88
  22. package/dist/ts/menu/menu.ts +302 -0
  23. package/dist/ts/sidebar/sidebar.ts +874 -0
  24. package/dist/ts/tab/tab.ts +2637 -0
  25. package/dist/ts/toolbar/toolbar.ts +2378 -0
  26. package/dist/ts/treeview/treeview.ts +5768 -0
  27. package/helpers/e2e/accordionHelper.js +70 -53
  28. package/helpers/e2e/contextmenuHelper.js +52 -35
  29. package/helpers/e2e/index.js +14 -12
  30. package/helpers/e2e/menuHelper.js +52 -35
  31. package/helpers/e2e/sidebarHelper.js +109 -92
  32. package/helpers/e2e/tabHelper.js +73 -56
  33. package/helpers/e2e/toolbarHelper.js +73 -56
  34. package/helpers/e2e/treeview.js +79 -61
  35. package/license +10 -10
  36. package/package.json +164 -164
  37. package/src/accordion/accordion-model.d.ts +190 -190
  38. package/src/accordion/accordion.js +19 -19
  39. package/src/breadcrumb/breadcrumb-model.d.ts +105 -105
  40. package/src/breadcrumb/breadcrumb.js +19 -19
  41. package/src/carousel/carousel-model.d.ts +148 -148
  42. package/src/carousel/carousel.js +19 -19
  43. package/src/common/h-scroll-model.d.ts +6 -6
  44. package/src/common/h-scroll.js +23 -21
  45. package/src/common/menu-base-model.d.ts +206 -206
  46. package/src/common/menu-base.js +31 -25
  47. package/src/common/v-scroll-model.d.ts +6 -6
  48. package/src/common/v-scroll.js +19 -19
  49. package/src/context-menu/context-menu-model.d.ts +18 -18
  50. package/src/context-menu/context-menu.js +19 -19
  51. package/src/menu/menu-model.d.ts +43 -43
  52. package/src/menu/menu.js +19 -19
  53. package/src/sidebar/sidebar-model.d.ts +191 -191
  54. package/src/sidebar/sidebar.js +19 -19
  55. package/src/tab/tab-model.d.ts +291 -291
  56. package/src/tab/tab.js +21 -21
  57. package/src/toolbar/toolbar-model.d.ts +195 -195
  58. package/src/toolbar/toolbar.js +23 -19
  59. package/src/treeview/treeview-model.d.ts +411 -411
  60. package/src/treeview/treeview.js +20 -20
  61. package/styles/accordion/_bds-definition.scss +167 -0
  62. package/styles/accordion/_bigger.scss +121 -0
  63. package/styles/accordion/_bootstrap5.3-definition.scss +168 -0
  64. package/styles/accordion/_fluent2-definition.scss +167 -0
  65. package/styles/accordion/_fusionnew-definition.scss +168 -0
  66. package/styles/accordion/_material3-dark-definition.scss +1 -0
  67. package/styles/accordion/_material3-definition.scss +168 -0
  68. package/styles/accordion/fluent2.scss +4 -0
  69. package/styles/accordion/icons/_bds.scss +15 -0
  70. package/styles/accordion/icons/_bootstrap5.3.scss +15 -0
  71. package/styles/accordion/icons/_fluent2.scss +15 -0
  72. package/styles/accordion/icons/_fusionnew.scss +15 -0
  73. package/styles/accordion/icons/_material3-dark.scss +1 -0
  74. package/styles/accordion/icons/_material3.scss +15 -0
  75. package/styles/accordion/material3-dark.scss +4 -0
  76. package/styles/accordion/material3.scss +4 -0
  77. package/styles/appbar/_all.scss +2 -0
  78. package/styles/appbar/_bds-definition.scss +25 -0
  79. package/styles/appbar/_bigger.scss +15 -0
  80. package/styles/appbar/_bootstrap-dark-definition.scss +6 -0
  81. package/styles/appbar/_bootstrap-definition.scss +6 -0
  82. package/styles/appbar/_bootstrap4-definition.scss +6 -0
  83. package/styles/appbar/_bootstrap5-definition.scss +6 -0
  84. package/styles/appbar/_bootstrap5.3-definition.scss +6 -0
  85. package/styles/appbar/_fabric-dark-definition.scss +6 -0
  86. package/styles/appbar/_fabric-definition.scss +6 -0
  87. package/styles/appbar/_fluent-definition.scss +6 -0
  88. package/styles/appbar/_fluent2-definition.scss +24 -0
  89. package/styles/appbar/_fusionnew-definition.scss +6 -0
  90. package/styles/appbar/_highcontrast-definition.scss +6 -0
  91. package/styles/appbar/_highcontrast-light-definition.scss +6 -0
  92. package/styles/appbar/_layout.scss +76 -0
  93. package/styles/appbar/_material-dark-definition.scss +6 -0
  94. package/styles/appbar/_material-definition.scss +6 -0
  95. package/styles/appbar/_material3-definition.scss +6 -0
  96. package/styles/appbar/_tailwind-definition.scss +6 -0
  97. package/styles/appbar/_theme.scss +216 -0
  98. package/styles/bootstrap-dark.css +1 -1
  99. package/styles/bootstrap.css +1 -1
  100. package/styles/bootstrap4.css +1 -1
  101. package/styles/bootstrap5-dark.css +1 -1
  102. package/styles/bootstrap5.css +1 -1
  103. package/styles/breadcrumb/_bds-definition.scss +60 -0
  104. package/styles/breadcrumb/_bigger.scss +160 -0
  105. package/styles/breadcrumb/_bootstrap5.3-definition.scss +61 -0
  106. package/styles/breadcrumb/_fluent2-definition.scss +61 -0
  107. package/styles/breadcrumb/_fusionnew-definition.scss +59 -0
  108. package/styles/breadcrumb/_layout.scss +1 -1
  109. package/styles/breadcrumb/_material3-dark-definition.scss +1 -0
  110. package/styles/breadcrumb/_material3-definition.scss +60 -0
  111. package/styles/breadcrumb/_tailwind-dark-definition.scss +1 -60
  112. package/styles/breadcrumb/_tailwind-definition.scss +3 -3
  113. package/styles/breadcrumb/bootstrap-dark.css +1 -1
  114. package/styles/breadcrumb/bootstrap.css +1 -1
  115. package/styles/breadcrumb/bootstrap4.css +1 -1
  116. package/styles/breadcrumb/bootstrap5-dark.css +1 -1
  117. package/styles/breadcrumb/bootstrap5.css +1 -1
  118. package/styles/breadcrumb/fabric-dark.css +1 -1
  119. package/styles/breadcrumb/fabric.css +1 -1
  120. package/styles/breadcrumb/fluent-dark.css +1 -1
  121. package/styles/breadcrumb/fluent.css +1 -1
  122. package/styles/breadcrumb/fluent2.scss +4 -0
  123. package/styles/breadcrumb/highcontrast-light.css +1 -1
  124. package/styles/breadcrumb/highcontrast.css +1 -1
  125. package/styles/breadcrumb/icons/_bds.scss +23 -0
  126. package/styles/breadcrumb/icons/_bootstrap5.3.scss +23 -0
  127. package/styles/breadcrumb/icons/_fluent2.scss +23 -0
  128. package/styles/breadcrumb/icons/_fusionnew.scss +23 -0
  129. package/styles/breadcrumb/icons/_material3-dark.scss +1 -0
  130. package/styles/breadcrumb/icons/_material3.scss +12 -0
  131. package/styles/breadcrumb/material-dark.css +1 -1
  132. package/styles/breadcrumb/material.css +1 -1
  133. package/styles/breadcrumb/material3-dark.scss +4 -0
  134. package/styles/breadcrumb/material3.scss +4 -0
  135. package/styles/breadcrumb/tailwind-dark.css +8 -8
  136. package/styles/breadcrumb/tailwind.css +8 -8
  137. package/styles/carousel/_bds-definition.scss +20 -0
  138. package/styles/carousel/_bootstrap5.3-definition.scss +20 -0
  139. package/styles/carousel/_fluent2-definition.scss +23 -0
  140. package/styles/carousel/_fusionnew-definition.scss +20 -0
  141. package/styles/carousel/_material3-dark-definition.scss +1 -0
  142. package/styles/carousel/_material3-definition.scss +21 -0
  143. package/styles/carousel/fluent2.scss +4 -0
  144. package/styles/carousel/icons/_bds.scss +30 -0
  145. package/styles/carousel/icons/_bootstrap5.3.scss +30 -0
  146. package/styles/carousel/icons/_fluent2.scss +30 -0
  147. package/styles/carousel/icons/_fusionnew.scss +30 -0
  148. package/styles/carousel/icons/_material3-dark.scss +1 -0
  149. package/styles/carousel/icons/_material3.scss +30 -0
  150. package/styles/carousel/material3-dark.scss +4 -0
  151. package/styles/carousel/material3.scss +4 -0
  152. package/styles/context-menu/_bds-definition.scss +68 -0
  153. package/styles/context-menu/_bigger.scss +96 -0
  154. package/styles/context-menu/_bootstrap5.3-definition.scss +52 -0
  155. package/styles/context-menu/_fluent2-definition.scss +52 -0
  156. package/styles/context-menu/_fusionnew-definition.scss +51 -0
  157. package/styles/context-menu/_material3-dark-definition.scss +1 -0
  158. package/styles/context-menu/_material3-definition.scss +51 -0
  159. package/styles/context-menu/fluent2.scss +4 -0
  160. package/styles/context-menu/icons/_bds.scss +31 -0
  161. package/styles/context-menu/icons/_bootstrap5.3.scss +31 -0
  162. package/styles/context-menu/icons/_fluent2.scss +31 -0
  163. package/styles/context-menu/icons/_fusionnew.scss +31 -0
  164. package/styles/context-menu/icons/_material3-dark.scss +1 -0
  165. package/styles/context-menu/icons/_material3.scss +31 -0
  166. package/styles/context-menu/material3-dark.scss +4 -0
  167. package/styles/context-menu/material3.scss +4 -0
  168. package/styles/fabric-dark.css +1 -1
  169. package/styles/fabric.css +1 -1
  170. package/styles/fluent-dark.css +1 -1
  171. package/styles/fluent.css +1 -1
  172. package/styles/fluent2.scss +34 -0
  173. package/styles/h-scroll/_bds-definition.scss +83 -0
  174. package/styles/h-scroll/_bigger.scss +39 -0
  175. package/styles/h-scroll/_bootstrap5.3-definition.scss +83 -0
  176. package/styles/h-scroll/_fluent2-definition.scss +83 -0
  177. package/styles/h-scroll/_fusionnew-definition.scss +83 -0
  178. package/styles/h-scroll/_material3-dark-definition.scss +1 -0
  179. package/styles/h-scroll/_material3-definition.scss +83 -0
  180. package/styles/h-scroll/fluent2.scss +4 -0
  181. package/styles/h-scroll/icons/_bds.scss +49 -0
  182. package/styles/h-scroll/icons/_bootstrap5.3.scss +49 -0
  183. package/styles/h-scroll/icons/_fluent2.scss +49 -0
  184. package/styles/h-scroll/icons/_fusionnew.scss +49 -0
  185. package/styles/h-scroll/icons/_material3-dark.scss +1 -0
  186. package/styles/h-scroll/icons/_material3.scss +49 -0
  187. package/styles/h-scroll/material3-dark.scss +4 -0
  188. package/styles/h-scroll/material3.scss +4 -0
  189. package/styles/highcontrast-light.css +1 -1
  190. package/styles/highcontrast.css +1 -1
  191. package/styles/material-dark.css +1 -1
  192. package/styles/material.css +1 -1
  193. package/styles/material3-dark.scss +34 -0
  194. package/styles/material3.scss +34 -0
  195. package/styles/menu/_bds-definition.scss +65 -0
  196. package/styles/menu/_bigger.scss +355 -0
  197. package/styles/menu/_bootstrap5.3-definition.scss +66 -0
  198. package/styles/menu/_fluent2-definition.scss +67 -0
  199. package/styles/menu/_fusionnew-definition.scss +66 -0
  200. package/styles/menu/_material3-dark-definition.scss +1 -0
  201. package/styles/menu/_material3-definition.scss +66 -0
  202. package/styles/menu/fluent2.scss +7 -0
  203. package/styles/menu/icons/_bds.scss +104 -0
  204. package/styles/menu/icons/_bootstrap5.3.scss +104 -0
  205. package/styles/menu/icons/_fluent2.scss +104 -0
  206. package/styles/menu/icons/_fusionnew.scss +104 -0
  207. package/styles/menu/icons/_material3-dark.scss +1 -0
  208. package/styles/menu/icons/_material3.scss +104 -0
  209. package/styles/menu/material3-dark.scss +7 -0
  210. package/styles/menu/material3.scss +7 -0
  211. package/styles/pager/_all.scss +2 -0
  212. package/styles/pager/_bds-definition.scss +152 -0
  213. package/styles/pager/_bigger.scss +311 -0
  214. package/styles/pager/_bootstrap-dark-definition.scss +151 -0
  215. package/styles/pager/_bootstrap-definition.scss +151 -0
  216. package/styles/pager/_bootstrap4-definition.scss +151 -0
  217. package/styles/pager/_bootstrap5-definition.scss +166 -0
  218. package/styles/pager/_bootstrap5.3-definition.scss +166 -0
  219. package/styles/pager/_fabric-dark-definition.scss +149 -0
  220. package/styles/pager/_fabric-definition.scss +149 -0
  221. package/styles/pager/_fluent-definition.scss +153 -0
  222. package/styles/pager/_fluent2-definition.scss +152 -0
  223. package/styles/pager/_fusionnew-definition.scss +166 -0
  224. package/styles/pager/_highcontrast-definition.scss +149 -0
  225. package/styles/pager/_highcontrast-light-definition.scss +149 -0
  226. package/styles/pager/_layout.scss +742 -0
  227. package/styles/pager/_material-dark-definition.scss +150 -0
  228. package/styles/pager/_material-definition.scss +150 -0
  229. package/styles/pager/_material3-definition.scss +166 -0
  230. package/styles/pager/_tailwind-definition.scss +152 -0
  231. package/styles/pager/_theme.scss +189 -0
  232. package/styles/pager/icons/_bds.scss +50 -0
  233. package/styles/pager/icons/_bootstrap-dark.scss +50 -0
  234. package/styles/pager/icons/_bootstrap.scss +50 -0
  235. package/styles/pager/icons/_bootstrap4.scss +50 -0
  236. package/styles/pager/icons/_bootstrap5.3.scss +50 -0
  237. package/styles/pager/icons/_bootstrap5.scss +50 -0
  238. package/styles/pager/icons/_fabric-dark.scss +50 -0
  239. package/styles/pager/icons/_fabric.scss +50 -0
  240. package/styles/pager/icons/_fluent.scss +50 -0
  241. package/styles/pager/icons/_fluent2.scss +50 -0
  242. package/styles/pager/icons/_fusionnew.scss +50 -0
  243. package/styles/pager/icons/_highcontrast-light.scss +50 -0
  244. package/styles/pager/icons/_highcontrast.scss +46 -0
  245. package/styles/pager/icons/_material-dark.scss +50 -0
  246. package/styles/pager/icons/_material.scss +46 -0
  247. package/styles/pager/icons/_material3.scss +50 -0
  248. package/styles/pager/icons/_tailwind.scss +50 -0
  249. package/styles/sidebar/_bds-definition.scss +53 -0
  250. package/styles/sidebar/_bootstrap5.3-definition.scss +6 -0
  251. package/styles/sidebar/_fluent2-definition.scss +8 -0
  252. package/styles/sidebar/_fusionnew-definition.scss +6 -0
  253. package/styles/sidebar/_material3-dark-definition.scss +1 -0
  254. package/styles/sidebar/_material3-definition.scss +4 -0
  255. package/styles/sidebar/fluent2.scss +3 -0
  256. package/styles/sidebar/material3-dark.scss +3 -0
  257. package/styles/sidebar/material3.scss +3 -0
  258. package/styles/stepper/_all.scss +2 -0
  259. package/styles/stepper/_bds-definition.scss +72 -0
  260. package/styles/stepper/_bigger.scss +53 -0
  261. package/styles/stepper/_bootstrap-dark-definition.scss +72 -0
  262. package/styles/stepper/_bootstrap-definition.scss +72 -0
  263. package/styles/stepper/_bootstrap4-definition.scss +72 -0
  264. package/styles/stepper/_bootstrap5-definition.scss +73 -0
  265. package/styles/stepper/_bootstrap5.3-definition.scss +72 -0
  266. package/styles/stepper/_fabric-dark-definition.scss +72 -0
  267. package/styles/stepper/_fabric-definition.scss +72 -0
  268. package/styles/stepper/_fluent-definition.scss +72 -0
  269. package/styles/stepper/_fluent2-definition.scss +72 -0
  270. package/styles/stepper/_fusionnew-definition.scss +72 -0
  271. package/styles/stepper/_highcontrast-definition.scss +72 -0
  272. package/styles/stepper/_highcontrast-light-definition.scss +72 -0
  273. package/styles/stepper/_layout.scss +431 -0
  274. package/styles/stepper/_material-dark-definition.scss +72 -0
  275. package/styles/stepper/_material-definition.scss +72 -0
  276. package/styles/stepper/_material3-definition.scss +72 -0
  277. package/styles/stepper/_tailwind-definition.scss +72 -0
  278. package/styles/stepper/_theme.scss +195 -0
  279. package/styles/stepper/icons/_bds.scss +5 -0
  280. package/styles/stepper/icons/_bootstrap-dark.scss +5 -0
  281. package/styles/stepper/icons/_bootstrap.scss +5 -0
  282. package/styles/stepper/icons/_bootstrap4.scss +5 -0
  283. package/styles/stepper/icons/_bootstrap5.3.scss +5 -0
  284. package/styles/stepper/icons/_bootstrap5.scss +5 -0
  285. package/styles/stepper/icons/_fabric-dark.scss +5 -0
  286. package/styles/stepper/icons/_fabric.scss +5 -0
  287. package/styles/stepper/icons/_fluent.scss +5 -0
  288. package/styles/stepper/icons/_fluent2.scss +5 -0
  289. package/styles/stepper/icons/_fusionnew.scss +5 -0
  290. package/styles/stepper/icons/_highcontrast-light.scss +5 -0
  291. package/styles/stepper/icons/_highcontrast.scss +5 -0
  292. package/styles/stepper/icons/_material-dark.scss +5 -0
  293. package/styles/stepper/icons/_material.scss +5 -0
  294. package/styles/stepper/icons/_material3.scss +5 -0
  295. package/styles/stepper/icons/_tailwind.scss +5 -0
  296. package/styles/tab/_bds-definition.scss +661 -0
  297. package/styles/tab/_bigger.scss +1270 -0
  298. package/styles/tab/_bootstrap5.3-definition.scss +636 -0
  299. package/styles/tab/_fluent2-definition.scss +667 -0
  300. package/styles/tab/_fusionnew-definition.scss +634 -0
  301. package/styles/tab/_material3-dark-definition.scss +1 -0
  302. package/styles/tab/_material3-definition.scss +636 -0
  303. package/styles/tab/fluent2.scss +5 -0
  304. package/styles/tab/icons/_bds.scss +90 -0
  305. package/styles/tab/icons/_bootstrap5.3.scss +90 -0
  306. package/styles/tab/icons/_fluent2.scss +98 -0
  307. package/styles/tab/icons/_fusionnew.scss +90 -0
  308. package/styles/tab/icons/_material3-dark.scss +1 -0
  309. package/styles/tab/icons/_material3.scss +90 -0
  310. package/styles/tab/material3-dark.scss +5 -0
  311. package/styles/tab/material3.scss +5 -0
  312. package/styles/tailwind-dark.css +8 -8
  313. package/styles/tailwind.css +8 -8
  314. package/styles/toolbar/_bds-definition.scss +197 -0
  315. package/styles/toolbar/_bigger.scss +309 -0
  316. package/styles/toolbar/_bootstrap5.3-definition.scss +198 -0
  317. package/styles/toolbar/_fluent2-definition.scss +198 -0
  318. package/styles/toolbar/_fusionnew-definition.scss +198 -0
  319. package/styles/toolbar/_material3-dark-definition.scss +1 -0
  320. package/styles/toolbar/_material3-definition.scss +199 -0
  321. package/styles/toolbar/fluent2.scss +6 -0
  322. package/styles/toolbar/icons/_bds.scss +14 -0
  323. package/styles/toolbar/icons/_bootstrap5.3.scss +14 -0
  324. package/styles/toolbar/icons/_fluent2.scss +14 -0
  325. package/styles/toolbar/icons/_fusionnew.scss +14 -0
  326. package/styles/toolbar/icons/_material3-dark.scss +1 -0
  327. package/styles/toolbar/icons/_material3.scss +14 -0
  328. package/styles/toolbar/material3-dark.scss +6 -0
  329. package/styles/toolbar/material3.scss +6 -0
  330. package/styles/treeview/_bds-definition.scss +132 -0
  331. package/styles/treeview/_bigger.scss +393 -0
  332. package/styles/treeview/_bootstrap5.3-definition.scss +119 -0
  333. package/styles/treeview/_fluent2-definition.scss +128 -0
  334. package/styles/treeview/_fusionnew-definition.scss +120 -0
  335. package/styles/treeview/_material3-dark-definition.scss +1 -0
  336. package/styles/treeview/_material3-definition.scss +110 -0
  337. package/styles/treeview/fluent2.scss +4 -0
  338. package/styles/treeview/icons/_bds.scss +44 -0
  339. package/styles/treeview/icons/_bootstrap5.3.scss +44 -0
  340. package/styles/treeview/icons/_fluent2.scss +44 -0
  341. package/styles/treeview/icons/_fusionnew.scss +44 -0
  342. package/styles/treeview/icons/_material3-dark.scss +1 -0
  343. package/styles/treeview/icons/_material3.scss +44 -0
  344. package/styles/treeview/material3-dark.scss +4 -0
  345. package/styles/treeview/material3.scss +4 -0
  346. package/styles/v-scroll/_bds-definition.scss +49 -0
  347. package/styles/v-scroll/_bigger.scss +28 -0
  348. package/styles/v-scroll/_bootstrap5.3-definition.scss +49 -0
  349. package/styles/v-scroll/_fluent2-definition.scss +49 -0
  350. package/styles/v-scroll/_fusionnew-definition.scss +49 -0
  351. package/styles/v-scroll/_material3-dark-definition.scss +1 -0
  352. package/styles/v-scroll/_material3-definition.scss +49 -0
  353. package/styles/v-scroll/fluent2.scss +4 -0
  354. package/styles/v-scroll/icons/_bds.scss +27 -0
  355. package/styles/v-scroll/icons/_bootstrap5.3.scss +27 -0
  356. package/styles/v-scroll/icons/_fluent2.scss +27 -0
  357. package/styles/v-scroll/icons/_fusionnew.scss +27 -0
  358. package/styles/v-scroll/icons/_material3-dark.scss +1 -0
  359. package/styles/v-scroll/icons/_material3.scss +27 -0
  360. package/styles/v-scroll/material3-dark.scss +4 -0
  361. package/styles/v-scroll/material3.scss +4 -0
  362. package/tslint.json +111 -111
  363. package/.github/PULL_REQUEST_TEMPLATE/Bug.md +0 -63
  364. package/.github/PULL_REQUEST_TEMPLATE/feature.md +0 -39
  365. package/accordion.d.ts +0 -4
  366. package/accordion.js +0 -4
  367. package/breadcrumb.d.ts +0 -4
  368. package/breadcrumb.js +0 -4
  369. package/carousel.d.ts +0 -4
  370. package/carousel.js +0 -4
  371. package/common.d.ts +0 -4
  372. package/common.js +0 -4
  373. package/context-menu.d.ts +0 -4
  374. package/context-menu.js +0 -4
  375. package/helpers/e2e/accordionHelper.d.ts +0 -56
  376. package/helpers/e2e/contextmenuHelper.d.ts +0 -37
  377. package/helpers/e2e/index.d.ts +0 -7
  378. package/helpers/e2e/menuHelper.d.ts +0 -37
  379. package/helpers/e2e/sidebarHelper.d.ts +0 -94
  380. package/helpers/e2e/tabHelper.d.ts +0 -60
  381. package/helpers/e2e/toolbarHelper.d.ts +0 -60
  382. package/helpers/e2e/treeview.d.ts +0 -50
  383. package/index.d.ts +0 -4
  384. package/index.js +0 -4
  385. package/menu.d.ts +0 -4
  386. package/menu.js +0 -4
  387. package/sidebar.d.ts +0 -4
  388. package/sidebar.js +0 -4
  389. package/src/accordion/accordion.d.ts +0 -440
  390. package/src/accordion/index.d.ts +0 -5
  391. package/src/breadcrumb/breadcrumb.d.ts +0 -255
  392. package/src/breadcrumb/index.d.ts +0 -5
  393. package/src/carousel/carousel.d.ts +0 -338
  394. package/src/carousel/index.d.ts +0 -3
  395. package/src/common/h-scroll.d.ts +0 -105
  396. package/src/common/index.d.ts +0 -9
  397. package/src/common/menu-base.d.ts +0 -526
  398. package/src/common/menu-scroll.d.ts +0 -29
  399. package/src/common/v-scroll.d.ts +0 -106
  400. package/src/context-menu/index.d.ts +0 -5
  401. package/src/index.d.ts +0 -13
  402. package/src/menu/index.d.ts +0 -5
  403. package/src/menu/menu.d.ts +0 -121
  404. package/src/sidebar/index.d.ts +0 -5
  405. package/src/sidebar/sidebar.d.ts +0 -321
  406. package/src/tab/index.d.ts +0 -5
  407. package/src/tab/tab.d.ts +0 -650
  408. package/src/toolbar/index.d.ts +0 -5
  409. package/src/toolbar/toolbar.d.ts +0 -470
  410. package/src/treeview/index.d.ts +0 -5
  411. package/src/treeview/treeview.d.ts +0 -1256
  412. package/tab.d.ts +0 -4
  413. package/tab.js +0 -4
  414. package/toolbar.d.ts +0 -4
  415. package/toolbar.js +0 -4
  416. package/treeview.d.ts +0 -4
  417. package/treeview.js +0 -4
@@ -0,0 +1,2637 @@
1
+ import { Component, Property, Event, EmitType, closest, Collection, Complex, attributes, detach, Instance, isNullOrUndefined } from '@syncfusion/ej2-base';
2
+ import { INotifyPropertyChanged, NotifyPropertyChanges, ChildProperty, select, isVisible } from '@syncfusion/ej2-base';
3
+ import { KeyboardEvents, KeyboardEventArgs, MouseEventArgs, Effect, Browser, formatUnit, DomElements, L10n } from '@syncfusion/ej2-base';
4
+ import { setStyleAttribute as setStyle, isNullOrUndefined as isNOU, selectAll, addClass, removeClass, remove } from '@syncfusion/ej2-base';
5
+ import { EventHandler, rippleEffect, Touch, SwipeEventArgs, compile, Animation, AnimationModel, BaseEventArgs } from '@syncfusion/ej2-base';
6
+ import { getRandomId, SanitizeHtmlHelper, Draggable, DragEventArgs as DragArgs, DropEventArgs } from '@syncfusion/ej2-base';
7
+ import { Base } from '@syncfusion/ej2-base';
8
+ import { Popup, PopupModel } from '@syncfusion/ej2-popups';
9
+ import { Toolbar, OverflowMode, ClickEventArgs } from '../toolbar/toolbar';
10
+ import { TabModel, TabItemModel, HeaderModel, TabActionSettingsModel, TabAnimationSettingsModel } from './tab-model';
11
+ import { ToolbarModel } from '../toolbar';
12
+
13
+ type HTEle = HTMLElement;
14
+ type Str = string;
15
+
16
+ /**
17
+ * Options to set the orientation of Tab header.
18
+ */
19
+ export type HeaderPosition = 'Top' | 'Bottom' | 'Left' | 'Right';
20
+ /**
21
+ * Options to set the content element height adjust modes.
22
+ */
23
+ export type HeightStyles = 'None' | 'Auto' | 'Content' | 'Fill';
24
+ /**
25
+ * Specifies the options of Tab content display mode.
26
+ */
27
+ export type ContentLoad = 'Dynamic' | 'Init' | 'Demand';
28
+
29
+ const CLS_TAB: string = 'e-tab';
30
+ const CLS_HEADER: string = 'e-tab-header';
31
+ const CLS_BLA_TEM: string = 'blazor-template';
32
+ const CLS_CONTENT: string = 'e-content';
33
+ const CLS_NEST: string = 'e-nested';
34
+ const CLS_ITEMS: string = 'e-items';
35
+ const CLS_ITEM: string = 'e-item';
36
+ const CLS_TEMPLATE: string = 'e-template';
37
+ const CLS_RTL: string = 'e-rtl';
38
+ const CLS_ACTIVE: string = 'e-active';
39
+ const CLS_DISABLE: string = 'e-disable';
40
+ const CLS_HIDDEN: string = 'e-hidden';
41
+ const CLS_FOCUS: string = 'e-focused';
42
+ const CLS_ICONS: string = 'e-icons';
43
+ const CLS_ICON: string = 'e-icon';
44
+ const CLS_ICON_TAB: string = 'e-icon-tab';
45
+ const CLS_ICON_CLOSE: string = 'e-close-icon';
46
+ const CLS_CLOSE_SHOW: string = 'e-close-show';
47
+ const CLS_TEXT: string = 'e-tab-text';
48
+ const CLS_INDICATOR: string = 'e-indicator';
49
+ const CLS_WRAP: string = 'e-tab-wrap';
50
+ const CLS_TEXT_WRAP: string = 'e-text-wrap';
51
+ const CLS_TAB_ICON: string = 'e-tab-icon';
52
+ const CLS_TB_ITEMS: string = 'e-toolbar-items';
53
+ const CLS_TB_ITEM: string = 'e-toolbar-item';
54
+ const CLS_TB_POP: string = 'e-toolbar-pop';
55
+ const CLS_TB_POPUP: string = 'e-toolbar-popup';
56
+ const CLS_HOR_NAV: string = 'e-hor-nav';
57
+ const CLS_POPUP_OPEN: string = 'e-popup-open';
58
+ const CLS_POPUP_CLOSE: string = 'e-popup-close';
59
+ const CLS_PROGRESS: string = 'e-progress';
60
+ const CLS_IGNORE: string = 'e-ignore';
61
+ const CLS_OVERLAY: string = 'e-overlay';
62
+ const CLS_HSCRCNT: string = 'e-hscroll-content';
63
+ const CLS_VSCRCNT: string = 'e-vscroll-content';
64
+ const CLS_VTAB: string = 'e-vertical-tab';
65
+ const CLS_VERTICAL: string = 'e-vertical';
66
+ const CLS_VLEFT: string = 'e-vertical-left';
67
+ const CLS_VRIGHT: string = 'e-vertical-right';
68
+ const CLS_HBOTTOM: string = 'e-horizontal-bottom';
69
+ const CLS_FILL: string = 'e-fill-mode';
70
+ const TABITEMPREFIX: string = 'tabitem_';
71
+ const CLS_REORDER_ACTIVE_ITEM: string = 'e-reorder-active-item';
72
+
73
+ /** An interface that holds options to control the selected item action. */
74
+ export interface SelectEventArgs extends BaseEventArgs {
75
+ /** Defines the previous Tab item element. */
76
+ previousItem: HTMLElement
77
+ /** Defines the previous Tab item index. */
78
+ previousIndex: number
79
+ /** Defines the selected Tab item element. */
80
+ selectedItem: HTMLElement
81
+ /** Defines the selected Tab item index. */
82
+ selectedIndex: number
83
+ /** Defines the content selection done through swiping. */
84
+ isSwiped: boolean
85
+ /** Defines the prevent action. */
86
+ cancel?: boolean
87
+ /** Defines the selected content. */
88
+ selectedContent: HTMLElement
89
+ /** Determines whether the event is triggered via user interaction or programmatic way. True, if the event is triggered by user interaction. */
90
+ isInteracted?: boolean
91
+ }
92
+ /** An interface that holds options to control the selecting item action. */
93
+ export interface SelectingEventArgs extends SelectEventArgs {
94
+ /** Defines the selecting Tab item element. */
95
+ selectingItem: HTMLElement
96
+ /** Defines the selecting Tab item index. */
97
+ selectingIndex: number
98
+ /** Defines the selecting Tab item content. */
99
+ selectingContent: HTMLElement
100
+ /** Defines the type of the event. */
101
+ event?: Event
102
+ }
103
+ /** An interface that holds options to control the removing and removed item action. */
104
+ export interface RemoveEventArgs extends BaseEventArgs {
105
+ /** Defines the removed Tab item element. */
106
+ removedItem: HTMLElement
107
+ /** Defines the removed Tab item index. */
108
+ removedIndex: number
109
+ /** Defines the prevent action. */
110
+ cancel?: boolean
111
+ }
112
+ /** An interface that holds options to control the adding and added item action. */
113
+ export interface AddEventArgs extends BaseEventArgs {
114
+ /** Defines the added Tab item element */
115
+ addedItems: TabItemModel[]
116
+ /** Defines the prevent action. */
117
+ cancel?: boolean
118
+ }
119
+ /** An interface that holds option to control the dragging and dragged item action. */
120
+ export interface DragEventArgs extends BaseEventArgs {
121
+ /** Defines the current dragged Tab item. */
122
+ draggedItem: HTMLElement
123
+ /** Defines the dropped Tab item. */
124
+ droppedItem: HTMLElement
125
+ /** defines the Dragged Tab item index. */
126
+ index: number
127
+ /** Return the actual event. */
128
+ event: MouseEvent
129
+ /** Return the target element */
130
+ target: HTMLElement
131
+ /** Return the clone element */
132
+ clonedElement: HTMLElement
133
+ /** Defines the prevent action. */
134
+ cancel?: boolean
135
+ }
136
+ /**
137
+ * Objects used for configuring the Tab selecting item action properties.
138
+ */
139
+ export class TabActionSettings extends ChildProperty<TabActionSettings> {
140
+ /**
141
+ * Specifies the animation effect for displaying Tab content.
142
+ *
143
+ * @default 'SlideLeftIn'
144
+ * @aspType string
145
+ */
146
+ @Property('SlideLeftIn')
147
+ public effect: 'None' | Effect;
148
+ /**
149
+ * Specifies the time duration to transform content.
150
+ *
151
+ * @default 600
152
+ */
153
+ @Property(600)
154
+ public duration: number;
155
+ /**
156
+ * Specifies easing effect applied while transforming content.
157
+ *
158
+ * @default 'ease'
159
+ */
160
+ @Property('ease')
161
+ public easing: string;
162
+ }
163
+ /**
164
+ * Objects used for configuring the Tab animation properties.
165
+ */
166
+ export class TabAnimationSettings extends ChildProperty<TabAnimationSettings> {
167
+ /**
168
+ * Specifies the animation to appear while moving to previous Tab content.
169
+ *
170
+ * @default { effect: 'SlideLeftIn', duration: 600, easing: 'ease' }
171
+ */
172
+ @Complex<TabActionSettingsModel>({ effect: 'SlideLeftIn', duration: 600, easing: 'ease' }, TabActionSettings)
173
+ public previous: TabActionSettingsModel;
174
+ /**
175
+ * Specifies the animation to appear while moving to next Tab content.
176
+ *
177
+ * @default { effect: 'SlideRightIn', duration: 600, easing: 'ease' }
178
+ */
179
+ @Complex<TabActionSettingsModel>({ effect: 'SlideRightIn', duration: 600, easing: 'ease' }, TabActionSettings)
180
+ public next: TabActionSettingsModel;
181
+ }
182
+ /**
183
+ * Objects used for configuring the Tab item header properties.
184
+ */
185
+ export class Header extends ChildProperty<Header> {
186
+ /**
187
+ * Specifies the display text of the Tab item header.
188
+ *
189
+ * @default ''
190
+ */
191
+ @Property('')
192
+ public text: string | HTMLElement;
193
+ /**
194
+ * Specifies the icon class that is used to render an icon in the Tab header.
195
+ *
196
+ * @default ''
197
+ */
198
+ @Property('')
199
+ public iconCss: string;
200
+ /**
201
+ * Options for positioning the icon in the Tab item header. This property depends on `iconCss` property.
202
+ * The possible values are:
203
+ * - Left: Places the icon to the `left` of the item.
204
+ * - Top: Places the icon on the `top` of the item.
205
+ * - Right: Places the icon to the `right` end of the item.
206
+ * - Bottom: Places the icon at the `bottom` of the item.
207
+ *
208
+ * @default 'left'
209
+ */
210
+ @Property('left')
211
+ public iconPosition: string;
212
+ }
213
+ /**
214
+ * An array of object that is used to configure the Tab.
215
+ */
216
+ export class TabItem extends ChildProperty<TabItem> {
217
+ /**
218
+ * The object used for configuring the Tab item header properties.
219
+ *
220
+ * @default {}
221
+ */
222
+ @Complex<HeaderModel>({}, Header)
223
+ public header: HeaderModel;
224
+ /**
225
+ * Specifies the header text of Tab item.
226
+ *
227
+ * @default null
228
+ */
229
+ @Property(null)
230
+ public headerTemplate: string;
231
+ /**
232
+ * Specifies the content of Tab item, that is displayed when concern item header is selected.
233
+ *
234
+ * @default ''
235
+ */
236
+ @Property('')
237
+ public content: string | HTMLElement;
238
+ /**
239
+ * Sets the CSS classes to the Tab item to customize its styles.
240
+ *
241
+ * @default ''
242
+ */
243
+ @Property('')
244
+ public cssClass: string;
245
+ /**
246
+ * Sets true to disable user interactions of the Tab item.
247
+ *
248
+ * @default false
249
+ */
250
+ @Property(false)
251
+ public disabled: boolean;
252
+ /**
253
+ * Sets false to hide the Tab item.
254
+ *
255
+ * @default true
256
+ */
257
+ @Property(true)
258
+ public visible: boolean;
259
+ /**
260
+ * Sets unique ID to Tab item.
261
+ *
262
+ * @default null
263
+ */
264
+ @Property()
265
+ public id: string;
266
+ }
267
+
268
+ /** @hidden */
269
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
270
+ interface EJ2Instance extends HTMLElement {
271
+ /* eslint-disable */
272
+ ej2_instances: Object[]
273
+ }
274
+
275
+ /**
276
+ * Tab is a content panel to show multiple contents in a single space, one at a time.
277
+ * Each Tab item has an associated content, that will be displayed based on the active Tab header item.
278
+ * ```html
279
+ * <div id="tab"></div>
280
+ * <script>
281
+ * var tabObj = new Tab();
282
+ * tab.appendTo("#tab");
283
+ * </script>
284
+ * ```
285
+ */
286
+ @NotifyPropertyChanges
287
+ export class Tab extends Component<HTMLElement> implements INotifyPropertyChanged {
288
+ private hdrEle: HTEle;
289
+ private cntEle: HTEle;
290
+ private tbObj: Toolbar;
291
+ public tabId: string;
292
+ private tbItems: HTEle;
293
+ private tbItem: HTEle[];
294
+ private tbPop: HTEle;
295
+ private isTemplate: boolean;
296
+ private isPopup: boolean;
297
+ private isReplace: boolean;
298
+ private prevIndex: number;
299
+ private prevItem: HTEle;
300
+ private popEle: DomElements;
301
+ private actEleId: string;
302
+ private bdrLine: HTEle;
303
+ private popObj: Popup;
304
+ private btnCls: HTEle;
305
+ private cnt: string;
306
+ private show: object = {};
307
+ private hide: object = {};
308
+ private enableAnimation: boolean;
309
+ private keyModule: KeyboardEvents;
310
+ private tabKeyModule: KeyboardEvents;
311
+ private touchModule: Touch;
312
+ private maxHeight: number = 0;
313
+ private title: Str = 'Close';
314
+ private initRender: boolean;
315
+ private isInteracted: boolean = false;
316
+ private prevActiveEle: string;
317
+ private lastIndex: number = 0;
318
+ private isSwipeed: boolean;
319
+ private isNested: boolean;
320
+ private itemIndexArray: string[];
321
+ private templateEle: string[];
322
+ private scrCntClass: string;
323
+ private isAdd: boolean = false;
324
+ private content: HTEle;
325
+ private selectedID: string;
326
+ private selectingID: string;
327
+ private isIconAlone: boolean = false;
328
+ private dragItem: HTMLElement;
329
+ private cloneElement: HTMLElement;
330
+ private droppedIndex: number;
331
+ private draggingItems: TabItemModel[];
332
+ private draggableItems: Draggable[] = [];
333
+ private tbId: string;
334
+ private resizeContext: EventListenerObject = this.refreshActiveTabBorder.bind(this);
335
+ /**
336
+ * Contains the keyboard configuration of the Tab.
337
+ */
338
+ private keyConfigs: { [key: string]: Str } = {
339
+ tab: 'tab',
340
+ home: 'home',
341
+ end: 'end',
342
+ enter: 'enter',
343
+ space: 'space',
344
+ delete: 'delete',
345
+ moveLeft: 'leftarrow',
346
+ moveRight: 'rightarrow',
347
+ moveUp: 'uparrow',
348
+ moveDown: 'downarrow'
349
+ };
350
+ /**
351
+ * An array of object that is used to configure the Tab component.
352
+ * ```typescript
353
+ * let tabObj: Tab = new Tab( {
354
+ * items: [
355
+ * { header: { text: 'TabItem1' }, content: 'Tab Item1 Content' },
356
+ * { header: { text: 'TabItem2' }, content: 'Tab Item2 Content' }
357
+ * ]
358
+ * });
359
+ * tabObj.appendTo('#tab');
360
+ * ```
361
+ *
362
+ * @default []
363
+ */
364
+ @Collection<TabItemModel>([], TabItem)
365
+ public items: TabItemModel[];
366
+ /**
367
+ * Specifies the width of the Tab component. Default, Tab width sets based on the width of its parent.
368
+ *
369
+ * @default '100%'
370
+ */
371
+ @Property('100%')
372
+ public width: string | number;
373
+ /**
374
+ * Specifies the height of the Tab component. By default, Tab height is set based on the height of its parent.
375
+ * To use height property, heightAdjustMode must be set to 'None'.
376
+ *
377
+ * @default 'auto'
378
+ */
379
+ @Property('auto')
380
+ public height: string | number;
381
+ /**
382
+ * Sets the CSS classes to root element of the Tab that helps to customize component styles.
383
+ *
384
+ * @default ''
385
+ */
386
+ @Property('')
387
+ public cssClass: string;
388
+ /**
389
+ * Specifies the index for activating the current Tab item.
390
+ * ```typescript
391
+ * let tabObj: Tab = new Tab( {
392
+ * selectedItem: 1,
393
+ * items: [
394
+ * { header: { text: 'TabItem1' }, content: 'Tab Item1 Content' },
395
+ * { header: { text: 'TabItem2' }, content: 'Tab Item2 Content' }
396
+ * ]
397
+ * });
398
+ * tabObj.appendTo('#tab');
399
+ * ```
400
+ *
401
+ * @default 0
402
+ */
403
+ @Property(0)
404
+ public selectedItem: number;
405
+ /**
406
+ * Specifies the orientation of Tab header.
407
+ * The possible values are:
408
+ * - Top: Places the Tab header on the top.
409
+ * - Bottom: Places the Tab header at the bottom.
410
+ * - Left: Places the Tab header on the left.
411
+ * - Right: Places the Tab header at the right.
412
+ *
413
+ * @default 'Top'
414
+ */
415
+ @Property('Top')
416
+ public headerPlacement: HeaderPosition;
417
+ /**
418
+ * Specifies the height style for Tab content.
419
+ * The possible values are:
420
+ * - None: Based on the given height property, the content panel height is set.
421
+ * - Auto: Tallest panel height of a given Tab content is set to all the other panels.
422
+ * - Content: Based on the corresponding content height, the content panel height is set.
423
+ * - Fill: Based on the parent height, the content panel height is set.
424
+ *
425
+ * @default 'Content'
426
+ */
427
+ @Property('Content')
428
+ public heightAdjustMode: HeightStyles;
429
+ /**
430
+ * Specifies the Tab display mode when Tab content exceeds the viewing area.
431
+ * The possible modes are:
432
+ * - Scrollable: All the elements are displayed in a single line with horizontal scrolling enabled.
433
+ * - Popup: Tab container holds the items that can be placed within the available space and rest of the items are moved to the popup.
434
+ * If the popup content overflows the height of the page, the rest of the elements can be viewed by scrolling the popup.
435
+ *
436
+ * @default 'Scrollable'
437
+ */
438
+ @Property('Scrollable')
439
+ public overflowMode: OverflowMode;
440
+ /**
441
+ * Specifies the modes for Tab content.
442
+ * The possible modes are:
443
+ * `Dynamic` Load Tab content dynamically at the time of switching it's header.
444
+ * `Init` Load all tab contents at initial load.
445
+ * `Demand` Load Tab content when required but keep content once it is rendered.
446
+ *
447
+ * @default 'Dynamic'
448
+ */
449
+ @Property('Dynamic')
450
+ protected loadOn: ContentLoad;
451
+ /**
452
+ * Enable or disable persisting component's state between page reloads.
453
+ * If enabled, following list of states will be persisted.
454
+ * 1. selectedItem
455
+ *
456
+ * @default false
457
+ */
458
+ @Property(false)
459
+ public enablePersistence: boolean;
460
+ /**
461
+ * Defines whether to allow the cross-scripting site or not.
462
+ *
463
+ * @default false
464
+ */
465
+ @Property(false)
466
+ public enableHtmlSanitizer: boolean;
467
+ /**
468
+ * Specifies whether to show the close button for header items to remove the item from the Tab.
469
+ *
470
+ * @default false
471
+ */
472
+ @Property(false)
473
+ public showCloseButton: boolean;
474
+ /**
475
+ * Determines whether to re-order tab items to show active tab item in the header area or popup when OverflowMode is Popup.
476
+ * True, if active tab item should be visible in header area instead of pop-up. The default value is true.
477
+ *
478
+ * @default true
479
+ */
480
+ @Property(true)
481
+ public reorderActiveTab: boolean;
482
+ /**
483
+ * Specifies the scrolling distance in scroller.
484
+ *
485
+ * @default null
486
+ */
487
+ @Property()
488
+ public scrollStep: number;
489
+ /**
490
+ * Defines the area in which the draggable element movement will be occurring. Outside that area will be restricted
491
+ * for the draggable element movement. By default, the draggable element movement occurs in the toolbar.
492
+ * @default null
493
+ */
494
+ @Property()
495
+ public dragArea: string;
496
+ /**
497
+ * Sets true to allow drag and drop the Tab items
498
+ * @default false
499
+ */
500
+ @Property(false)
501
+ public allowDragAndDrop: boolean;
502
+ /**
503
+ * Specifies the animation configuration settings while showing the content of the Tab.
504
+ *
505
+ * @default
506
+ * { previous: { effect: 'SlideLeftIn', duration: 600, easing: 'ease' },
507
+ * next: { effect: 'SlideRightIn', duration: 600, easing: 'ease' } }
508
+ */
509
+ @Complex<TabAnimationSettingsModel>({}, TabAnimationSettings)
510
+ public animation: TabAnimationSettingsModel;
511
+ /**
512
+ * The event will be fired once the component rendering is completed.
513
+ *
514
+ * @event
515
+ */
516
+ @Event()
517
+ public created: EmitType<Event>;
518
+ /**
519
+ * The event will be fired before adding the item to the Tab.
520
+ *
521
+ * @event
522
+ */
523
+ @Event()
524
+ public adding: EmitType<AddEventArgs>;
525
+ /**
526
+ * The event will be fired after adding the item to the Tab.
527
+ *
528
+ * @event
529
+ */
530
+ @Event()
531
+ public added: EmitType<AddEventArgs>;
532
+ /**
533
+ * The event will be fired before the item gets selected.
534
+ *
535
+ * @event
536
+ */
537
+ @Event()
538
+ public selecting: EmitType<SelectingEventArgs>;
539
+ /**
540
+ * The event will be fired after the item gets selected.
541
+ *
542
+ * @event
543
+ */
544
+ @Event()
545
+ public selected: EmitType<SelectEventArgs>;
546
+ /**
547
+ * The event will be fired before removing the item from the Tab.
548
+ *
549
+ * @event
550
+ */
551
+ @Event()
552
+ public removing: EmitType<RemoveEventArgs>;
553
+ /**
554
+ * The event will be fired after removing the item from the Tab.
555
+ *
556
+ * @event
557
+ */
558
+ @Event()
559
+ public removed: EmitType<RemoveEventArgs>;
560
+ /**
561
+ * The event will be fired before dragging the item from Tab
562
+ * @event
563
+ */
564
+ @Event()
565
+ public onDragStart: EmitType<DragEventArgs>;
566
+ /**
567
+ * The event will be fired while dragging the Tab item
568
+ * @event
569
+ */
570
+ @Event()
571
+ public dragging: EmitType<DragEventArgs>;
572
+ /**
573
+ * The event will be fired after dropping the Tab item
574
+ * @event
575
+ */
576
+ @Event()
577
+ public dragged: EmitType<DragEventArgs>;
578
+ /**
579
+ * The event will be fired when the component gets destroyed.
580
+ *
581
+ * @event
582
+ */
583
+ @Event()
584
+ public destroyed: EmitType<Event>;
585
+ /**
586
+ * Removes the component from the DOM and detaches all its related event handlers, attributes and classes.
587
+ *
588
+ * @returns {void}
589
+ */
590
+ public destroy(): void {
591
+ if ((this as any).isReact || (this as any).isAngular) {
592
+ this.clearTemplate();
593
+ }
594
+ if (!isNOU(this.tbObj)) {
595
+ this.tbObj.destroy();
596
+ this.tbObj = null;
597
+ }
598
+ this.unWireEvents();
599
+ ['role', 'aria-disabled', 'aria-activedescendant', 'tabindex', 'aria-orientation'].forEach((val: string): void => {
600
+ this.element.removeAttribute(val);
601
+ });
602
+ this.expTemplateContent();
603
+ if (!this.isTemplate) {
604
+ while (this.element.firstElementChild) {
605
+ remove(this.element.firstElementChild);
606
+ }
607
+ } else {
608
+ const cntEle: Element = select('.' + CLS_TAB + ' > .' + CLS_CONTENT, this.element);
609
+ this.element.classList.remove(CLS_TEMPLATE);
610
+ if (!isNOU(cntEle)) {
611
+ cntEle.innerHTML = this.cnt;
612
+ }
613
+ }
614
+
615
+ if (this.btnCls) {
616
+ this.btnCls = null;
617
+ }
618
+ this.hdrEle = null;
619
+ this.cntEle = null;
620
+ this.tbItems = null;
621
+ this.tbItem = null;
622
+ this.tbPop = null;
623
+ this.prevItem = null;
624
+ this.popEle = null;
625
+ this.bdrLine = null;
626
+ this.content = null;
627
+ this.dragItem = null;
628
+ this.cloneElement = null;
629
+ this.draggingItems = [];
630
+ if (this.draggableItems && this.draggableItems.length > 0) {
631
+ for (let i: number = 0; i < this.draggableItems.length; i++) {
632
+ this.draggableItems[i].destroy();
633
+ this.draggableItems[i] = null;
634
+ }
635
+ this.draggableItems = [];
636
+ }
637
+ super.destroy();
638
+ this.trigger('destroyed');
639
+ }
640
+
641
+ /**
642
+ * Refresh the tab component
643
+ *
644
+ * @returns {void}
645
+ */
646
+ public refresh(): void {
647
+ if ((this as any).isReact) {
648
+ this.clearTemplate();
649
+ }
650
+ super.refresh();
651
+ if ((this as any).isReact) {
652
+ this.renderReactTemplates();
653
+ }
654
+ }
655
+
656
+ /**
657
+ * Initialize component
658
+ *
659
+ * @private
660
+ * @returns {void}
661
+ */
662
+ protected preRender(): void {
663
+ const nested: Element = closest(this.element, '.' + CLS_CONTENT);
664
+ this.prevIndex = 0;
665
+ this.isNested = false;
666
+ this.isPopup = false;
667
+ this.initRender = true;
668
+ this.isSwipeed = false;
669
+ this.itemIndexArray = [];
670
+ this.templateEle = [];
671
+ if (this.allowDragAndDrop) {
672
+ this.dragArea = !isNOU(this.dragArea) ? this.dragArea : '#' + this.element.id + ' ' + ('.' + CLS_HEADER);
673
+ }
674
+ if (!isNOU(nested)) {
675
+ nested.parentElement.classList.add(CLS_NEST);
676
+ this.isNested = true;
677
+ }
678
+ const name: Str = Browser.info.name;
679
+ const css: Str = (name === 'msie') ? 'e-ie' : (name === 'edge') ? 'e-edge' : (name === 'safari') ? 'e-safari' : '';
680
+ setStyle(this.element, { 'width': formatUnit(this.width), 'height': formatUnit(this.height) });
681
+ this.setCssClass(this.element, this.cssClass, true);
682
+ attributes(this.element, { role: 'tablist', 'aria-disabled': 'false', 'aria-activedescendant': '' });
683
+ this.setCssClass(this.element, css, true);
684
+ this.updatePopAnimationConfig();
685
+ }
686
+ /**
687
+ * Initializes a new instance of the Tab class.
688
+ *
689
+ * @param {TabModel} options - Specifies Tab model properties as options.
690
+ * @param {string | HTMLElement} element - Specifies the element that is rendered as a Tab.
691
+ */
692
+ public constructor(options?: TabModel, element?: string | HTMLElement) {
693
+ super(options, <HTEle | Str>element);
694
+ }
695
+ /**
696
+ * Initialize the component rendering
697
+ *
698
+ * @private
699
+ * @returns {void}
700
+ */
701
+ protected render(): void {
702
+ this.btnCls = this.createElement('span', { className: CLS_ICONS + ' ' + CLS_ICON_CLOSE, attrs: { title: this.title } });
703
+ this.tabId = this.element.id.length > 0 ? ('-' + this.element.id) : getRandomId();
704
+ this.renderContainer();
705
+ this.wireEvents();
706
+ this.initRender = false;
707
+ }
708
+ private renderContainer(): void {
709
+ const ele: HTEle = this.element;
710
+ this.items.forEach((item: TabItemModel, index: number) => {
711
+ if (isNOU(item.id) && !isNOU((item as Base<HTMLElement>).setProperties)) {
712
+ (item as Base<HTMLElement>).setProperties({ id: TABITEMPREFIX + index.toString() }, true);
713
+ }
714
+ });
715
+ if (this.items.length > 0 && ele.children.length === 0) {
716
+ ele.appendChild(this.createElement('div', { className: CLS_CONTENT }));
717
+ this.setOrientation(this.headerPlacement, this.createElement('div', { className: CLS_HEADER }));
718
+ this.isTemplate = false;
719
+ } else if (this.element.children.length > 0) {
720
+ this.isTemplate = true;
721
+ ele.classList.add(CLS_TEMPLATE);
722
+ const header: HTEle = <HTEle>ele.querySelector('.' + CLS_HEADER);
723
+ if (header && this.headerPlacement === 'Bottom') {
724
+ this.setOrientation(this.headerPlacement, header);
725
+ }
726
+ }
727
+ if (!isNOU(select('.' + CLS_HEADER, this.element)) && !isNOU(select('.' + CLS_CONTENT, this.element))) {
728
+ this.renderHeader();
729
+ this.tbItems = <HTEle>select('.' + CLS_HEADER + ' .' + CLS_TB_ITEMS, this.element);
730
+ if (!isNOU(this.tbItems)) {
731
+ rippleEffect(this.tbItems, { selector: '.e-tab-wrap' });
732
+ }
733
+ this.renderContent();
734
+ if (selectAll('.' + CLS_TB_ITEM, this.element).length > 0) {
735
+ this.tbItems = <HTEle>select('.' + CLS_HEADER + ' .' + CLS_TB_ITEMS, this.element);
736
+ this.bdrLine = this.createElement('div', { className: CLS_INDICATOR + ' ' + CLS_HIDDEN + ' ' + CLS_IGNORE });
737
+ const scrCnt: HTEle = <HTEle>select('.' + this.scrCntClass, this.tbItems);
738
+ if (!isNOU(scrCnt)) {
739
+ scrCnt.insertBefore(this.bdrLine, scrCnt.firstChild);
740
+ } else {
741
+ this.tbItems.insertBefore(this.bdrLine, this.tbItems.firstChild);
742
+ }
743
+ this.setContentHeight(true);
744
+ this.select(this.selectedItem);
745
+ }
746
+ if (!isNOU(this.tbItem)) {
747
+ for (let i: number = 0; i < this.items.length; i++) {
748
+ const tabID: string = this.items[i].id;
749
+ this.tbItem[i].setAttribute('data-id', tabID);
750
+ }
751
+ }
752
+ this.setRTL(this.enableRtl);
753
+ }
754
+ }
755
+
756
+ private serverItemsChanged(): void {
757
+ this.enableAnimation = false;
758
+ this.setActive(this.selectedItem, true);
759
+ if (this.loadOn !== 'Dynamic' && !isNOU(this.cntEle)) {
760
+ const itemCollection: HTMLElement[] = [].slice.call(this.cntEle.children);
761
+ const content: string = CLS_CONTENT + this.tabId + '_' + this.selectedItem;
762
+ itemCollection.forEach((item: HTEle) => {
763
+ if (item.classList.contains(CLS_ACTIVE) && item.id !== content) {
764
+ item.classList.remove(CLS_ACTIVE);
765
+ }
766
+ if (item.id === content) {
767
+ item.classList.add(CLS_ACTIVE);
768
+ }
769
+ });
770
+ this.prevIndex = this.selectedItem;
771
+ this.triggerAnimation(CLS_ITEM + this.tabId + '_' + this.selectedItem, false);
772
+ }
773
+ this.enableAnimation = true;
774
+ }
775
+
776
+ private headerReady(): void {
777
+ this.initRender = true;
778
+ this.hdrEle = this.getTabHeader();
779
+ this.setOrientation(this.headerPlacement, this.hdrEle);
780
+ if (!isNOU(this.hdrEle)) {
781
+ this.tbObj = (<ToolbarModel>(this.hdrEle && (<Instance>this.hdrEle).ej2_instances[0])) as Toolbar;
782
+ }
783
+ this.tbObj.clicked = this.clickHandler.bind(this);
784
+ this.tbObj.on('onItemsChanged', this.serverItemsChanged.bind(this));
785
+ this.tbItems = <HTEle>select('.' + CLS_HEADER + ' .' + CLS_TB_ITEMS, this.element);
786
+ if (!isNOU(this.tbItems)) {
787
+ rippleEffect(this.tbItems, { selector: '.e-tab-wrap' });
788
+ }
789
+ if (selectAll('.' + CLS_TB_ITEM, this.element).length > 0) {
790
+ this.bdrLine = <HTEle>select('.' + CLS_INDICATOR + '.' + CLS_IGNORE, this.element);
791
+ const scrollCnt: HTEle = <HTEle>select('.' + this.scrCntClass, this.tbItems);
792
+ if (!isNOU(scrollCnt)) {
793
+ scrollCnt.insertBefore(this.bdrLine, scrollCnt.firstElementChild);
794
+ } else {
795
+ this.tbItems.insertBefore(this.bdrLine, this.tbItems.firstElementChild);
796
+ }
797
+ this.select(this.selectedItem);
798
+ }
799
+ this.cntEle = <HTEle>select('.' + CLS_TAB + ' > .' + CLS_CONTENT, this.element);
800
+ if (!isNOU(this.cntEle)) {
801
+ this.touchModule = new Touch(this.cntEle, { swipe: this.swipeHandler.bind(this) });
802
+ }
803
+ if (this.loadOn === 'Demand') {
804
+ const id: string = this.setActiveContent();
805
+ this.triggerAnimation(id, false);
806
+ }
807
+ this.initRender = false;
808
+ this.renderComplete();
809
+ }
810
+
811
+ private setActiveContent(): string {
812
+ const id: string = CLS_ITEM + this.tabId + '_' + this.selectedItem;
813
+ const item: HTEle = this.getTrgContent(this.cntEle, this.extIndex(id));
814
+ if (!isNOU(item)) {
815
+ item.classList.add(CLS_ACTIVE);
816
+ }
817
+ return id;
818
+ }
819
+
820
+ private renderHeader(): void {
821
+ const hdrPlace: HeaderPosition = this.headerPlacement;
822
+ let tabItems: Object[] = [];
823
+ this.hdrEle = this.getTabHeader();
824
+ this.addVerticalClass();
825
+ if (!this.isTemplate) {
826
+ tabItems = this.parseObject(this.items, 0);
827
+ } else {
828
+ if (this.element.children.length > 1 && this.element.children[1].classList.contains(CLS_HEADER)) {
829
+ this.setProperties({ headerPlacement: 'Bottom' }, true);
830
+ }
831
+ const count: number = this.hdrEle.children.length;
832
+ const hdrItems: string[] = [];
833
+ for (let i: number = 0; i < count; i++) {
834
+ hdrItems.push(this.hdrEle.children.item(i).innerHTML);
835
+ }
836
+ if (count > 0) {
837
+ while (this.hdrEle.firstElementChild) {
838
+ detach(this.hdrEle.firstElementChild);
839
+ }
840
+ const tabItems: HTMLElement = this.createElement('div', { className: CLS_ITEMS });
841
+ this.hdrEle.appendChild(tabItems);
842
+ hdrItems.forEach((item: string, index: number) => {
843
+ this.lastIndex = index;
844
+ const attr: object = {
845
+ className: CLS_ITEM, id: CLS_ITEM + this.tabId + '_' + index,
846
+ attrs: { role: 'tab', 'aria-controls': CLS_CONTENT + this.tabId + '_' + index, 'aria-selected': 'false' }
847
+ };
848
+ const txt: Str = this.createElement('span', {
849
+ className: CLS_TEXT, innerHTML: item, attrs: { 'role': 'presentation' }
850
+ }).outerHTML;
851
+ const cont: Str = this.createElement('div', {
852
+ className: CLS_TEXT_WRAP, innerHTML: txt + this.btnCls.outerHTML
853
+ }).outerHTML;
854
+ const wrap: HTEle = this.createElement('div', { className: CLS_WRAP, innerHTML: cont, attrs: { tabIndex: '-1' } });
855
+ tabItems.appendChild(this.createElement('div', attr));
856
+ selectAll('.' + CLS_ITEM, tabItems)[index].appendChild(wrap);
857
+ });
858
+ }
859
+ }
860
+ this.tbObj = new Toolbar({
861
+ width: (hdrPlace === 'Left' || hdrPlace === 'Right') ? 'auto' : '100%',
862
+ height: (hdrPlace === 'Left' || hdrPlace === 'Right') ? '100%' : 'auto',
863
+ overflowMode: this.overflowMode,
864
+ items: (tabItems.length !== 0) ? tabItems : [],
865
+ clicked: this.clickHandler.bind(this),
866
+ scrollStep: this.scrollStep,
867
+ enableHtmlSanitizer: this.enableHtmlSanitizer
868
+
869
+ });
870
+ this.tbObj.isStringTemplate = true;
871
+ this.tbObj.createElement = this.createElement;
872
+ this.tbObj.appendTo(<HTEle>this.hdrEle);
873
+ attributes(this.hdrEle, { 'aria-label': 'tab-header' });
874
+ this.updateOrientationAttribute();
875
+ this.setCloseButton(this.showCloseButton);
876
+ }
877
+ private renderContent(): void {
878
+ this.cntEle = <HTEle>select('.' + CLS_CONTENT, this.element);
879
+ const hdrItem: HTEle[] = selectAll('.' + CLS_TB_ITEM, this.element);
880
+ if (this.isTemplate) {
881
+ this.cnt = (this.cntEle.children.length > 0) ? this.cntEle.innerHTML : '';
882
+ const contents: HTMLCollection = this.cntEle.children;
883
+ for (let i: number = 0; i < hdrItem.length; i++) {
884
+ if (contents.length - 1 >= i) {
885
+ addClass([contents.item(i)], CLS_ITEM);
886
+ attributes(contents.item(i), { 'role': 'tabpanel', 'aria-labelledby': CLS_ITEM + this.tabId + '_' + i });
887
+ contents.item(i).id = CLS_CONTENT + this.tabId + '_' + i;
888
+ }
889
+ }
890
+ }
891
+ }
892
+ private reRenderItems(): void {
893
+ this.renderContainer();
894
+ if (!isNOU(this.cntEle)) {
895
+ this.touchModule = new Touch(this.cntEle, { swipe: this.swipeHandler.bind(this) });
896
+ }
897
+ }
898
+ private parseObject(items: TabItemModel[], index: number): object[] {
899
+ const tbItems: HTMLElement[] = selectAll('.e-tab-header .' + CLS_TB_ITEM, this.element);
900
+ let maxId: number = this.lastIndex;
901
+ if (!this.isReplace && tbItems.length > 0) {
902
+ const idList: number[] = [];
903
+ tbItems.forEach((item: HTMLElement) => {
904
+ idList.push(parseInt(item.id.slice(item.id.indexOf('_') + 1), 10));
905
+ });
906
+ maxId = Math.max(...idList);
907
+ }
908
+ const tItems: Object[] = [];
909
+ let txtWrapEle: HTEle;
910
+ const spliceArray: number[] = [];
911
+ const i: number = 0;
912
+ items.forEach((item: TabItemModel, i: number) => {
913
+ const pos: Str = (isNOU(item.header) || isNOU(item.header.iconPosition)) ? '' : item.header.iconPosition;
914
+ const css: Str = (isNOU(item.header) || isNOU(item.header.iconCss)) ? '' : item.header.iconCss;
915
+ if ((isNOU(item.headerTemplate)) && (isNOU(item.header) || isNOU(item.header.text) ||
916
+ (((<string>item.header.text).length === 0)) && (css === ''))) {
917
+ spliceArray.push(i);
918
+ return;
919
+ }
920
+ let txt: Str | HTEle = item.headerTemplate || item.header.text;
921
+ if (typeof txt === 'string' && this.enableHtmlSanitizer) {
922
+ txt = SanitizeHtmlHelper.sanitize(<Str>txt);
923
+ }
924
+ let itemIndex: number;
925
+ if (this.isReplace && !isNOU(this.tbId) && this.tbId !== '') {
926
+ const num: number = (this.tbId.indexOf('_'));
927
+ itemIndex = parseInt(this.tbId.substring(num + 1), 10);
928
+ this.tbId = '';
929
+ } else {
930
+ itemIndex = index + i;
931
+ }
932
+ this.lastIndex = ((tbItems.length === 0) ? i : ((this.isReplace) ? (itemIndex) : (maxId + 1 + i)));
933
+ const disabled: Str = (item.disabled) ? ' ' + CLS_DISABLE + ' ' + CLS_OVERLAY : '';
934
+ const hidden: Str = (item.visible === false) ? ' ' + CLS_HIDDEN : '';
935
+ txtWrapEle = this.createElement('div', { className: CLS_TEXT, attrs: { 'role': 'presentation' } });
936
+ const tHtml: Str = ((txt instanceof Object) ? (<HTEle>txt).outerHTML : txt);
937
+ const txtEmpty: boolean = (!isNOU(tHtml) && tHtml !== '');
938
+ if (!isNOU((<HTEle>txt).tagName)) {
939
+ txtWrapEle.appendChild(txt as HTEle);
940
+ } else {
941
+ this.headerTextCompile(txtWrapEle, txt as string, i);
942
+ }
943
+ let tEle: HTEle;
944
+ const icon: HTEle = this.createElement('span', {
945
+ className: CLS_ICONS + ' ' + CLS_TAB_ICON + ' ' + CLS_ICON + '-' + pos + ' ' + css
946
+ });
947
+ const tCont: HTEle = this.createElement('div', { className: CLS_TEXT_WRAP });
948
+ tCont.appendChild(txtWrapEle);
949
+ if ((txt !== '' && txt !== undefined) && css !== '') {
950
+ if ((pos === 'left' || pos === 'top')) {
951
+ tCont.insertBefore(icon, tCont.firstElementChild);
952
+ } else {
953
+ tCont.appendChild(icon);
954
+ }
955
+ tEle = txtWrapEle;
956
+ this.isIconAlone = false;
957
+ } else {
958
+ tEle = ((css === '') ? txtWrapEle : icon);
959
+ if (tEle === icon) {
960
+ detach(txtWrapEle);
961
+ tCont.appendChild(icon);
962
+ this.isIconAlone = true;
963
+ }
964
+ }
965
+ const wrapAttrs: { [key: string]: string } = (item.disabled) ? {} : { tabIndex: '-1' };
966
+ tCont.appendChild(this.btnCls.cloneNode(true));
967
+ const wrap: HTEle = this.createElement('div', { className: CLS_WRAP, attrs: wrapAttrs });
968
+ wrap.appendChild(tCont);
969
+ if (this.itemIndexArray === []) {
970
+ this.itemIndexArray.push(CLS_ITEM + this.tabId + '_' + this.lastIndex);
971
+ } else {
972
+ this.itemIndexArray.splice((index + i), 0, CLS_ITEM + this.tabId + '_' + this.lastIndex);
973
+ }
974
+ const attrObj: Object = {
975
+ id: CLS_ITEM + this.tabId + '_' + this.lastIndex, role: 'tab', 'aria-selected': 'false'
976
+ };
977
+ const tItem: { [key: string]: {} } = { htmlAttributes: attrObj, template: wrap };
978
+ tItem.cssClass = ((item.cssClass !== undefined) ? item.cssClass : ' ') + ' ' + disabled + ' ' + hidden + ' '
979
+ + ((css !== '') ? 'e-i' + pos : '') + ' ' + ((!txtEmpty) ? CLS_ICON : '');
980
+ if (pos === 'top' || pos === 'bottom') {
981
+ this.element.classList.add('e-vertical-icon');
982
+ }
983
+ tItems.push(tItem);
984
+ i++;
985
+ });
986
+ if (!this.isAdd) {
987
+ spliceArray.forEach((spliceItemIndex: number) => {
988
+ this.items.splice(spliceItemIndex, 1);
989
+ });
990
+ }
991
+ if (this.isIconAlone) {
992
+ this.element.classList.add(CLS_ICON_TAB);
993
+ } else {
994
+ this.element.classList.remove(CLS_ICON_TAB);
995
+ }
996
+ return tItems;
997
+ }
998
+ private removeActiveClass(): void {
999
+ const tabHeader: HTMLElement = this.getTabHeader();
1000
+ if (tabHeader) {
1001
+ const tabItems: HTMLElement[] = selectAll('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE, tabHeader);
1002
+ [].slice.call(tabItems).forEach((node: HTMLElement) => node.classList.remove(CLS_ACTIVE));
1003
+ }
1004
+ }
1005
+ private checkPopupOverflow(ele: HTEle): boolean {
1006
+ this.tbPop = <HTEle>select('.' + CLS_TB_POP, this.element);
1007
+ const popIcon: HTEle = (<HTEle>select('.e-hor-nav', this.element));
1008
+ const tbrItems: HTEle = (<HTEle>select('.' + CLS_TB_ITEMS, this.element));
1009
+ const lastChild: HTEle = <HTMLElement>tbrItems.lastChild;
1010
+ let isOverflow: boolean = false;
1011
+ if (!this.isVertical() && ((this.enableRtl && ((popIcon.offsetLeft + popIcon.offsetWidth) > tbrItems.offsetLeft))
1012
+ || (!this.enableRtl && popIcon.offsetLeft < tbrItems.offsetWidth))) {
1013
+ isOverflow = true;
1014
+ } else if (this.isVertical() && (popIcon.offsetTop < lastChild.offsetTop + lastChild.offsetHeight)) {
1015
+ isOverflow = true;
1016
+ }
1017
+ if (isOverflow) {
1018
+ ele.classList.add(CLS_TB_POPUP);
1019
+ this.tbPop.insertBefore(<Node>ele, selectAll('.' + CLS_TB_POPUP, this.tbPop)[0]);
1020
+ }
1021
+ return true;
1022
+ }
1023
+ private popupHandler(target: HTEle): number {
1024
+ const ripEle: HTEle = <HTEle>target.querySelector('.e-ripple-element');
1025
+ if (!isNOU(ripEle)) {
1026
+ ripEle.outerHTML = '';
1027
+ target.querySelector('.' + CLS_WRAP).classList.remove('e-ripple');
1028
+ }
1029
+ this.tbItem = selectAll('.' + CLS_TB_ITEMS + ' .' + CLS_TB_ITEM, this.hdrEle);
1030
+ const lastChild: HTEle = <HTEle>this.tbItem[this.tbItem.length - 1];
1031
+ if (this.tbItem.length !== 0) {
1032
+ target.classList.remove(CLS_TB_POPUP);
1033
+ target.removeAttribute('style');
1034
+ this.tbItems.appendChild(target);
1035
+ this.actEleId = target.id;
1036
+ if (this.checkPopupOverflow(lastChild)) {
1037
+ const prevEle: HTEle = <HTEle>(<HTEle>this.tbItems.lastChild).previousElementSibling;
1038
+ this.checkPopupOverflow(prevEle);
1039
+ }
1040
+ this.isPopup = true;
1041
+ }
1042
+ return selectAll('.' + CLS_TB_ITEM, this.tbItems).length - 1;
1043
+ }
1044
+ private updateOrientationAttribute(): void {
1045
+ attributes(this.element, { 'aria-orientation': (this.isVertical() ? 'vertical' : 'horizontal') });
1046
+ }
1047
+ private setCloseButton(val: boolean): void {
1048
+ const trg: Element = select('.' + CLS_HEADER, this.element);
1049
+ if (val === true) {
1050
+ trg.classList.add(CLS_CLOSE_SHOW);
1051
+ } else {
1052
+ trg.classList.remove(CLS_CLOSE_SHOW);
1053
+ }
1054
+ this.tbObj.refreshOverflow();
1055
+ this.refreshActiveTabBorder();
1056
+ }
1057
+ private prevCtnAnimation(prev: number, current: number): AnimationModel {
1058
+ let animation: AnimationModel;
1059
+ const checkRTL: boolean = this.enableRtl || this.element.classList.contains(CLS_RTL);
1060
+ if (this.isPopup || prev <= current) {
1061
+ if (this.animation.previous.effect === 'SlideLeftIn') {
1062
+ animation = {
1063
+ name: 'SlideLeftOut',
1064
+ duration: this.animation.previous.duration, timingFunction: this.animation.previous.easing
1065
+ };
1066
+ } else {
1067
+ animation = null;
1068
+ }
1069
+ } else {
1070
+ if (this.animation.next.effect === 'SlideRightIn') {
1071
+ animation = {
1072
+ name: 'SlideRightOut',
1073
+ duration: this.animation.next.duration, timingFunction: this.animation.next.easing
1074
+ };
1075
+ } else {
1076
+ animation = null;
1077
+ }
1078
+ }
1079
+ return animation;
1080
+ }
1081
+ private triggerPrevAnimation(oldCnt: HTEle, prevIndex: number): void {
1082
+ const animateObj: AnimationModel = this.prevCtnAnimation(prevIndex, this.selectedItem);
1083
+ if (!isNOU(animateObj)) {
1084
+ animateObj.begin = () => {
1085
+ setStyle(oldCnt, { 'position': 'absolute' });
1086
+ oldCnt.classList.add(CLS_PROGRESS);
1087
+ oldCnt.classList.add('e-view');
1088
+ };
1089
+ animateObj.end = () => {
1090
+ oldCnt.style.display = 'none';
1091
+ oldCnt.classList.remove(CLS_ACTIVE);
1092
+ oldCnt.classList.remove(CLS_PROGRESS);
1093
+ oldCnt.classList.remove('e-view');
1094
+ setStyle(oldCnt, { 'display': '', 'position': '' });
1095
+ if (oldCnt.childNodes.length === 0 && !this.isTemplate) {
1096
+ detach(oldCnt);
1097
+ }
1098
+ };
1099
+ new Animation(animateObj).animate(oldCnt);
1100
+ } else {
1101
+ oldCnt.classList.remove(CLS_ACTIVE);
1102
+ }
1103
+ }
1104
+ private triggerAnimation(id: Str, value: boolean): void {
1105
+ const prevIndex: number = this.prevIndex;
1106
+ let oldCnt: HTEle;
1107
+ const itemCollection: HTMLElement[] = [].slice.call(this.element.querySelector('.' + CLS_CONTENT).children);
1108
+ itemCollection.forEach((item: HTEle) => {
1109
+ if (item.id === this.prevActiveEle) {
1110
+ oldCnt = item;
1111
+ }
1112
+ });
1113
+ const prevEle: HTEle = this.tbItem[prevIndex];
1114
+ const newCnt: HTEle = this.getTrgContent(this.cntEle, this.extIndex(id));
1115
+ if (isNOU(oldCnt) && !isNOU(prevEle)) {
1116
+ const idNo: Str = this.extIndex(prevEle.id);
1117
+ oldCnt = this.getTrgContent(this.cntEle, idNo);
1118
+ }
1119
+ if (!isNOU(newCnt)) {
1120
+ this.prevActiveEle = newCnt.id;
1121
+ }
1122
+ if (this.initRender || value === false || this.animation === {} || isNOU(this.animation)) {
1123
+ if (oldCnt && oldCnt !== newCnt) {
1124
+ oldCnt.classList.remove(CLS_ACTIVE);
1125
+ }
1126
+ return;
1127
+ }
1128
+ const cnt: HTEle = <HTEle>select('.' + CLS_CONTENT, this.element);
1129
+ let animateObj: AnimationModel;
1130
+ if (this.prevIndex > this.selectedItem && !this.isPopup) {
1131
+ const openEff: Effect = <Effect>this.animation.previous.effect;
1132
+ animateObj = {
1133
+ name: <Effect>((openEff === <Effect>'None') ? '' : ((openEff !== <Effect>'SlideLeftIn') ? openEff : 'SlideLeftIn')),
1134
+ duration: this.animation.previous.duration,
1135
+ timingFunction: this.animation.previous.easing
1136
+ };
1137
+ } else if (this.isPopup || this.prevIndex < this.selectedItem || this.prevIndex === this.selectedItem) {
1138
+ const clsEff: Effect = <Effect>this.animation.next.effect;
1139
+ animateObj = {
1140
+ name: <Effect>((clsEff === <Effect>'None') ? '' : ((clsEff !== <Effect>'SlideRightIn') ? clsEff : 'SlideRightIn')),
1141
+ duration: this.animation.next.duration,
1142
+ timingFunction: this.animation.next.easing
1143
+ };
1144
+ }
1145
+ animateObj.progress = () => {
1146
+ cnt.classList.add(CLS_PROGRESS); this.setActiveBorder();
1147
+ };
1148
+ animateObj.end = () => {
1149
+ cnt.classList.remove(CLS_PROGRESS);
1150
+ newCnt.classList.add(CLS_ACTIVE);
1151
+ };
1152
+ if (!this.initRender && !isNOU(oldCnt)) {
1153
+ this.triggerPrevAnimation(oldCnt, prevIndex);
1154
+ }
1155
+ this.isPopup = false;
1156
+ if (animateObj.name === <Effect>'') {
1157
+ newCnt.classList.add(CLS_ACTIVE);
1158
+ } else {
1159
+ new Animation(animateObj).animate(newCnt);
1160
+ }
1161
+ }
1162
+ private keyPressed(trg: HTEle): void {
1163
+ const trgParent: HTEle = <HTEle>closest(trg, '.' + CLS_HEADER + ' .' + CLS_TB_ITEM);
1164
+ const trgIndex: number = this.getEleIndex(trgParent);
1165
+ if (!isNOU(this.popEle) && trg.classList.contains('e-hor-nav')) {
1166
+ (this.popEle.classList.contains(CLS_POPUP_OPEN)) ? this.popObj.hide(this.hide) : this.popObj.show(this.show);
1167
+ } else if (trg.classList.contains('e-scroll-nav')) {
1168
+ trg.click();
1169
+ } else {
1170
+ if (!isNOU(trgParent) && trgParent.classList.contains(CLS_ACTIVE) === false) {
1171
+ this.selectTab(trgIndex, null, true);
1172
+ if (!isNOU(this.popEle)) {
1173
+ this.popObj.hide(this.hide);
1174
+ }
1175
+ }
1176
+ }
1177
+ }
1178
+ private getTabHeader(): HTMLElement {
1179
+ if (isNOU(this.element)) {
1180
+ return undefined;
1181
+ }
1182
+ const headers: HTMLElement[] = [].slice.call(this.element.children).filter((e: HTMLElement) => e.classList.contains(CLS_HEADER));
1183
+ if (headers.length > 0) {
1184
+ return headers[0];
1185
+ } else {
1186
+ const wrap: HTMLElement =
1187
+ [].slice.call(this.element.children).filter((e: HTMLElement) => !e.classList.contains(CLS_BLA_TEM))[0];
1188
+ if (!wrap) {
1189
+ return undefined;
1190
+ }
1191
+ return [].slice.call(wrap.children).filter((e: HTMLElement) => e.classList.contains(CLS_HEADER))[0];
1192
+ }
1193
+ }
1194
+ private getEleIndex(item: HTEle): number {
1195
+ return Array.prototype.indexOf.call(selectAll('.' + CLS_TB_ITEM, this.getTabHeader()), item);
1196
+ }
1197
+ private extIndex(id: string): string {
1198
+ return id.replace(CLS_ITEM + this.tabId + '_', '');
1199
+ }
1200
+ private expTemplateContent(): void {
1201
+ this.templateEle.forEach((eleStr: Str): void => {
1202
+ if (!isNOU(this.element.querySelector(eleStr))) {
1203
+ (<HTEle>document.body.appendChild(this.element.querySelector(eleStr))).style.display = 'none';
1204
+ }
1205
+ });
1206
+ }
1207
+ private templateCompile(ele: HTEle, cnt: Str, index: number): void {
1208
+ const tempEle: HTEle = this.createElement('div');
1209
+ this.compileElement(tempEle, cnt, 'content', index);
1210
+ if (tempEle.childNodes.length !== 0) {
1211
+ ele.appendChild(tempEle);
1212
+ }
1213
+ if ((this as any).isReact) {
1214
+ this.renderReactTemplates();
1215
+ }
1216
+ }
1217
+ private compileElement(ele: HTEle, val: string, prop: string, index: number): void {
1218
+ let templateFn: Function;
1219
+ if (typeof val === 'string') {
1220
+ val = val.trim();
1221
+ if ((this as any).isVue) {
1222
+ templateFn = compile(SanitizeHtmlHelper.sanitize(val));
1223
+ } else {
1224
+ ele.innerHTML = SanitizeHtmlHelper.sanitize(val);
1225
+ }
1226
+ } else {
1227
+ templateFn = compile(val);
1228
+ }
1229
+ let templateFUN: HTMLElement[];
1230
+ if (!isNOU(templateFn)) {
1231
+ templateFUN = templateFn({}, this, prop);
1232
+ }
1233
+ if (!isNOU(templateFn) && templateFUN.length > 0) {
1234
+ [].slice.call(templateFUN).forEach((el: HTEle): void => {
1235
+ ele.appendChild(el);
1236
+ });
1237
+ }
1238
+ }
1239
+ private headerTextCompile(element: HTEle, text: string, index: number): void {
1240
+ this.compileElement(element, text, 'headerTemplate', index);
1241
+ }
1242
+ private getContent(ele: HTEle, cnt: Str | HTEle, callType: string, index: number): void {
1243
+ let eleStr: Str;
1244
+ cnt = isNOU(cnt) ? "" : cnt;
1245
+ if (typeof cnt === 'string' || isNOU((<HTEle>cnt).innerHTML)) {
1246
+ if (typeof cnt === 'string' && this.enableHtmlSanitizer) {
1247
+ cnt = SanitizeHtmlHelper.sanitize(<Str>cnt);
1248
+ }
1249
+ if ((<Str>cnt)[0] === '.' || (<Str>cnt)[0] === '#') {
1250
+ if (document.querySelectorAll(<string>cnt).length) {
1251
+ const eleVal: HTEle = <HTEle>document.querySelector(<string>cnt);
1252
+ eleStr = eleVal.outerHTML.trim();
1253
+ if (callType === 'clone') {
1254
+ ele.appendChild(eleVal.cloneNode(true));
1255
+ } else {
1256
+ ele.appendChild(eleVal);
1257
+ eleVal.style.display = '';
1258
+ }
1259
+ } else {
1260
+ this.templateCompile(ele, <Str>cnt, index);
1261
+ }
1262
+ } else {
1263
+ this.templateCompile(ele, <Str>cnt, index);
1264
+ }
1265
+ } else {
1266
+ ele.appendChild(cnt);
1267
+ }
1268
+ if (!isNOU(eleStr)) {
1269
+ if (this.templateEle.indexOf(cnt.toString()) === -1) {
1270
+ this.templateEle.push(cnt.toString());
1271
+ }
1272
+ }
1273
+ }
1274
+ private getTrgContent(cntEle: HTEle, no: Str): HTEle {
1275
+ let ele: HTEle;
1276
+ if (this.element.classList.contains(CLS_NEST)) {
1277
+ ele = <HTEle>select('.' + CLS_NEST + '> .' + CLS_CONTENT + ' > #' + CLS_CONTENT + this.tabId + '_' + no, this.element);
1278
+ } else {
1279
+ ele = this.findEle(cntEle.children, CLS_CONTENT + this.tabId + '_' + no);
1280
+ }
1281
+ return ele;
1282
+ }
1283
+ private findEle(items: HTMLCollection, key: Str): HTEle {
1284
+ let ele: HTEle;
1285
+ for (let i: number = 0; i < items.length; i++) {
1286
+ if (items[i].id === key) {
1287
+ ele = <HTEle>items[i];
1288
+ break;
1289
+ }
1290
+ }
1291
+ return ele;
1292
+ }
1293
+ private isVertical(): boolean {
1294
+ const isVertical: boolean = (this.headerPlacement === 'Left' || this.headerPlacement === 'Right') ? true : false;
1295
+ this.scrCntClass = (isVertical) ? CLS_VSCRCNT : CLS_HSCRCNT;
1296
+ return isVertical;
1297
+ }
1298
+ private addVerticalClass(): void {
1299
+ if (this.isVertical()) {
1300
+ const tbPos: string = (this.headerPlacement === 'Left') ? CLS_VLEFT : CLS_VRIGHT;
1301
+ addClass([this.hdrEle], [CLS_VERTICAL, tbPos]);
1302
+ if (!this.element.classList.contains(CLS_NEST)) {
1303
+ addClass([this.element], [CLS_VTAB, tbPos]);
1304
+ } else {
1305
+ addClass([this.hdrEle], [CLS_VTAB, tbPos]);
1306
+ }
1307
+ }
1308
+ if (this.headerPlacement === 'Bottom') {
1309
+ addClass([this.hdrEle], [CLS_HBOTTOM]);
1310
+ }
1311
+ }
1312
+ private updatePopAnimationConfig(): void {
1313
+ this.show = { name: (this.isVertical() ? 'FadeIn' : 'SlideDown'), duration: 100 };
1314
+ this.hide = { name: (this.isVertical() ? 'FadeOut' : 'SlideUp'), duration: 100 };
1315
+ }
1316
+ private changeOrientation(place: Str): void {
1317
+ this.setOrientation(place, this.hdrEle);
1318
+ const activeTab: HTMLElement = this.hdrEle.querySelector('.' + CLS_ACTIVE);
1319
+ const isVertical: boolean = this.hdrEle.classList.contains(CLS_VERTICAL) ? true : false;
1320
+ removeClass([this.element], [CLS_VTAB]);
1321
+ removeClass([this.hdrEle], [CLS_VERTICAL, CLS_VLEFT, CLS_VRIGHT]);
1322
+ if (isVertical !== this.isVertical()) {
1323
+ this.changeToolbarOrientation();
1324
+ if (!isNOU(activeTab) && activeTab.classList.contains(CLS_TB_POPUP)) {
1325
+ this.popupHandler(activeTab);
1326
+ }
1327
+ }
1328
+ this.addVerticalClass();
1329
+ this.updateOrientationAttribute();
1330
+ this.setActiveBorder();
1331
+ this.focusItem();
1332
+ }
1333
+
1334
+ private focusItem(): void {
1335
+ const curActItem: HTEle = <HTEle>select(' #' + CLS_ITEM + this.tabId + '_' + this.selectedItem, this.hdrEle);
1336
+ if (!isNOU(curActItem)) {
1337
+ (<HTEle>curActItem.firstElementChild).focus();
1338
+ }
1339
+ }
1340
+
1341
+ private changeToolbarOrientation(): void {
1342
+ this.tbObj.setProperties({ height: (this.isVertical() ? '100%' : 'auto'), width: (this.isVertical() ? 'auto' : '100%') }, true);
1343
+ this.tbObj.changeOrientation();
1344
+ this.updatePopAnimationConfig();
1345
+ }
1346
+
1347
+ private setOrientation(place: Str, ele: HTEle): void {
1348
+ const headerPos: number = Array.prototype.indexOf.call(this.element.children, ele);
1349
+ const contentPos: number = Array.prototype.indexOf.call(this.element.children, this.element.querySelector('.' + CLS_CONTENT));
1350
+ if (place === 'Bottom' && (contentPos > headerPos)) {
1351
+ this.element.appendChild(ele);
1352
+ } else {
1353
+ removeClass([ele], [CLS_HBOTTOM]);
1354
+ this.element.insertBefore(ele, select('.' + CLS_CONTENT, this.element));
1355
+ }
1356
+ }
1357
+ private setCssClass(ele: HTEle, cls: Str, val: boolean): void {
1358
+ if (cls === '') {
1359
+ return;
1360
+ }
1361
+ const list: Str[] = cls.split(' ');
1362
+ for (let i: number = 0; i < list.length; i++) {
1363
+ if (val) {
1364
+ ele.classList.add(list[i]);
1365
+ } else {
1366
+ ele.classList.remove(list[i]);
1367
+ }
1368
+ }
1369
+ }
1370
+ private setContentHeight(val: boolean): void {
1371
+ if (this.element.classList.contains(CLS_FILL)) {
1372
+ removeClass([this.element], [CLS_FILL]);
1373
+ }
1374
+ if (isNOU(this.cntEle)) {
1375
+ return;
1376
+ }
1377
+ const hdrEle: HTEle = this.getTabHeader();
1378
+ if (this.heightAdjustMode === 'None') {
1379
+ if (this.height === 'auto') {
1380
+ return;
1381
+ } else {
1382
+ if (!this.isVertical()) {
1383
+ setStyle(this.cntEle, { 'height': (this.element.offsetHeight - hdrEle.offsetHeight) + 'px' });
1384
+ }
1385
+ }
1386
+ } else if (this.heightAdjustMode === 'Fill') {
1387
+ addClass([this.element], [CLS_FILL]);
1388
+ setStyle(this.element, { 'height': '100%' });
1389
+ setStyle(this.cntEle, { 'height': (this.element.offsetHeight - hdrEle.offsetHeight) + 'px' });
1390
+ } else if (this.heightAdjustMode === 'Auto') {
1391
+ if (this.isTemplate === true) {
1392
+ const cnt: HTEle[] = selectAll('.' + CLS_CONTENT + ' > .' + CLS_ITEM, this.element);
1393
+ for (let i: number = 0; i < cnt.length; i++) {
1394
+ cnt[i].setAttribute('style', 'display:block; visibility: visible');
1395
+ this.maxHeight = Math.max(this.maxHeight, this.getHeight(cnt[i]));
1396
+ cnt[i].style.removeProperty('display');
1397
+ cnt[i].style.removeProperty('visibility');
1398
+ }
1399
+ } else {
1400
+ this.cntEle = <HTEle>select('.' + CLS_CONTENT, this.element);
1401
+ if (val === true) {
1402
+ this.cntEle.appendChild(this.createElement('div', {
1403
+ id: (CLS_CONTENT + this.tabId + '_' + 0), className: CLS_ITEM + ' ' + CLS_ACTIVE,
1404
+ attrs: { 'role': 'tabpanel', 'aria-labelledby': CLS_ITEM + this.tabId + '_' + 0 }
1405
+ }));
1406
+ }
1407
+ const ele: HTEle = <HTEle>this.cntEle.children.item(0);
1408
+ for (let i: number = 0; i < this.items.length; i++) {
1409
+ this.getContent(ele, this.items[i].content, 'clone', i);
1410
+ this.maxHeight = Math.max(this.maxHeight, this.getHeight(ele));
1411
+ while (ele.firstChild) {
1412
+ ele.removeChild(ele.firstChild);
1413
+ }
1414
+ }
1415
+ if ((this as any).isReact) {
1416
+ this.clearTemplate(['content']);
1417
+ }
1418
+ this.templateEle = [];
1419
+ this.getContent(ele, this.items[0].content, 'render', 0);
1420
+ if (this.prevIndex !== this.selectedItem) {
1421
+ ele.classList.remove(CLS_ACTIVE);
1422
+ }
1423
+ }
1424
+ setStyle(this.cntEle, { 'height': this.maxHeight + 'px' });
1425
+ } else {
1426
+ setStyle(this.cntEle, { 'height': 'auto' });
1427
+ }
1428
+ }
1429
+ private getHeight(ele: HTEle): number {
1430
+ const cs: CSSStyleDeclaration = window.getComputedStyle(ele);
1431
+ return ele.offsetHeight + parseFloat(cs.getPropertyValue('padding-top')) + parseFloat(cs.getPropertyValue('padding-bottom')) +
1432
+ parseFloat(cs.getPropertyValue('margin-top')) + parseFloat(cs.getPropertyValue('margin-bottom'));
1433
+ }
1434
+ private setActiveBorder(): void {
1435
+ const trgHdrEle: Element = this.getTabHeader();
1436
+ const trg: HTEle = <HTEle>select('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE, trgHdrEle);
1437
+ if (isNOU(trg)) {
1438
+ return;
1439
+ }
1440
+ if (!this.reorderActiveTab) {
1441
+ if (trg.classList.contains(CLS_TB_POPUP) && !this.bdrLine.classList.contains(CLS_HIDDEN)) {
1442
+ this.bdrLine.classList.add(CLS_HIDDEN);
1443
+ }
1444
+ if (trgHdrEle && !trgHdrEle.classList.contains(CLS_REORDER_ACTIVE_ITEM)) {
1445
+ trgHdrEle.classList.add(CLS_REORDER_ACTIVE_ITEM);
1446
+ }
1447
+ } else if (trgHdrEle) {
1448
+ trgHdrEle.classList.remove(CLS_REORDER_ACTIVE_ITEM);
1449
+ }
1450
+ const root: HTEle = <HTEle>closest(trg, '.' + CLS_TAB);
1451
+ if (this.element !== root) {
1452
+ return;
1453
+ }
1454
+ this.tbItems = <HTEle>select('.' + CLS_TB_ITEMS, trgHdrEle);
1455
+ const bar: HTEle = <HTEle>select('.' + CLS_INDICATOR, trgHdrEle);
1456
+ const scrollCnt: HTEle = <HTEle>select('.' + CLS_TB_ITEMS + ' .' + this.scrCntClass, trgHdrEle);
1457
+ if (this.isVertical()) {
1458
+ setStyle(bar, { 'left': '', 'right': '' });
1459
+ const tbHeight: number = (isNOU(scrollCnt)) ? this.tbItems.offsetHeight : scrollCnt.offsetHeight;
1460
+ if (tbHeight !== 0) {
1461
+ setStyle(bar, { 'top': trg.offsetTop + 'px', 'height': trg.offsetHeight + 'px' });
1462
+ } else {
1463
+ setStyle(bar, { 'top': 0, 'height': 0 });
1464
+ }
1465
+ } else {
1466
+ if (this.overflowMode === 'MultiRow') {
1467
+ let bar: HTEle = <HTEle>select('.' + CLS_INDICATOR, this.element);
1468
+ setStyle(bar, { 'top': trg.offsetHeight + trg.offsetTop + 'px', 'height': '' });
1469
+ } else {
1470
+ setStyle(bar, { 'top': '', 'height': '' });
1471
+ }
1472
+ let tbWidth: number = (isNOU(scrollCnt)) ? this.tbItems.offsetWidth : scrollCnt.offsetWidth;
1473
+ if (tbWidth !== 0) {
1474
+ setStyle(bar, { 'left': trg.offsetLeft + 'px', 'right': tbWidth - (trg.offsetLeft + trg.offsetWidth) + 'px' });
1475
+ } else {
1476
+ setStyle(bar, { 'left': 'auto', 'right': 'auto' });
1477
+ }
1478
+ }
1479
+ if (!isNOU(this.bdrLine) && !trg.classList.contains(CLS_TB_POPUP)) {
1480
+ this.bdrLine.classList.remove(CLS_HIDDEN);
1481
+ }
1482
+ }
1483
+ private setActive(value: number, skipDataBind: boolean = false, isInteracted: boolean = false): void {
1484
+ this.tbItem = selectAll('.' + CLS_TB_ITEM, this.getTabHeader());
1485
+ const trg: HTEle = this.tbItem[value];
1486
+ if (value < 0 || isNaN(value) || this.tbItem.length === 0) {
1487
+ return;
1488
+ }
1489
+ if (value >= 0 && !skipDataBind) {
1490
+ this.allowServerDataBinding = false;
1491
+ this.setProperties({ selectedItem: value }, true);
1492
+ this.allowServerDataBinding = true;
1493
+ if (!this.initRender) {
1494
+ this.serverDataBind();
1495
+ }
1496
+ }
1497
+ if (trg.classList.contains(CLS_ACTIVE)) {
1498
+ this.setActiveBorder();
1499
+ return;
1500
+ }
1501
+ if (!this.isTemplate) {
1502
+ const prev: HTEle = this.tbItem[this.prevIndex];
1503
+ if (!isNOU(prev)) {
1504
+ prev.removeAttribute('aria-controls');
1505
+ }
1506
+ attributes(trg, { 'aria-controls': CLS_CONTENT + this.tabId + '_' + value });
1507
+ }
1508
+ const id: Str = trg.id;
1509
+ this.removeActiveClass();
1510
+ trg.classList.add(CLS_ACTIVE);
1511
+ this.tbItem[this.prevIndex].setAttribute('aria-selected', 'false');
1512
+ trg.setAttribute('aria-selected', 'true');
1513
+ const no: number = Number(this.extIndex(id));
1514
+ if (isNOU(this.prevActiveEle)) {
1515
+ this.prevActiveEle = CLS_CONTENT + this.tabId + '_' + no;
1516
+ }
1517
+ attributes(this.element, { 'aria-activedescendant': id });
1518
+ if (this.isTemplate) {
1519
+ if (select('.' + CLS_CONTENT, this.element).children.length > 0) {
1520
+ const trg: HTEle = this.findEle(select('.' + CLS_CONTENT, this.element).children, CLS_CONTENT + this.tabId + '_' + no);
1521
+ if (!isNOU(trg)) {
1522
+ trg.classList.add(CLS_ACTIVE);
1523
+ }
1524
+ this.triggerAnimation(id, this.enableAnimation);
1525
+ }
1526
+ } else {
1527
+ this.cntEle = <HTEle>select('.' + CLS_TAB + ' > .' + CLS_CONTENT, this.element);
1528
+ const item: HTEle = this.getTrgContent(this.cntEle, this.extIndex(id));
1529
+ if (isNOU(item)) {
1530
+ this.cntEle.appendChild(this.createElement('div', {
1531
+ id: CLS_CONTENT + this.tabId + '_' + this.extIndex(id), className: CLS_ITEM + ' ' + CLS_ACTIVE,
1532
+ attrs: { role: 'tabpanel', 'aria-labelledby': CLS_ITEM + this.tabId + '_' + this.extIndex(id) }
1533
+ }));
1534
+ const eleTrg: HTEle = this.getTrgContent(this.cntEle, this.extIndex(id));
1535
+ const itemIndex: number = Array.prototype.indexOf.call(this.itemIndexArray, id);
1536
+ this.getContent(eleTrg, this.items[itemIndex].content, 'render', itemIndex);
1537
+ } else {
1538
+ item.classList.add(CLS_ACTIVE);
1539
+ }
1540
+ this.triggerAnimation(id, this.enableAnimation);
1541
+ }
1542
+ this.setActiveBorder();
1543
+ this.refreshItemVisibility(trg);
1544
+ if (!this.initRender && !skipDataBind) {
1545
+ (<HTEle>trg.firstElementChild).focus();
1546
+ const eventArg: SelectEventArgs = {
1547
+ previousItem: this.prevItem,
1548
+ previousIndex: this.prevIndex,
1549
+ selectedItem: trg,
1550
+ selectedIndex: value,
1551
+ selectedContent: <HTEle>select('#' + CLS_CONTENT + this.tabId + '_' + this.selectingID, this.content),
1552
+ isSwiped: this.isSwipeed,
1553
+ isInteracted: isInteracted
1554
+ };
1555
+ this.trigger('selected', eventArg);
1556
+ }
1557
+ }
1558
+
1559
+ private contentReady(): void {
1560
+ const id: string = this.setActiveContent();
1561
+ this.triggerAnimation(id, this.enableAnimation);
1562
+ }
1563
+
1564
+ private setItems(items: object[]): void {
1565
+ this.isReplace = true;
1566
+ this.tbItems = <HTEle>select('.' + CLS_TB_ITEMS, this.getTabHeader());
1567
+ this.tbObj.items = this.parseObject(items, 0);
1568
+ this.tbObj.dataBind();
1569
+ this.isReplace = false;
1570
+ }
1571
+ private setRTL(value: boolean): void {
1572
+ this.tbObj.enableRtl = value;
1573
+ this.tbObj.dataBind();
1574
+ this.setCssClass(this.element, CLS_RTL, value);
1575
+ this.refreshActiveBorder();
1576
+ }
1577
+ private refreshActiveBorder(): void {
1578
+ if (!isNOU(this.bdrLine)) {
1579
+ this.bdrLine.classList.add(CLS_HIDDEN);
1580
+ }
1581
+ this.setActiveBorder();
1582
+ }
1583
+ private showPopup(config: object): void {
1584
+ const tbPop: HTEle = <HTEle>select('.e-popup.e-toolbar-pop', this.hdrEle);
1585
+ if (tbPop.classList.contains('e-popup-close')) {
1586
+ const tbPopObj: Popup = (<PopupModel>(tbPop && (<Instance>tbPop).ej2_instances[0])) as Popup;
1587
+ tbPopObj.position.X = (this.headerPlacement === 'Left') ? 'left' : 'right';
1588
+ tbPopObj.dataBind();
1589
+ tbPopObj.show(config);
1590
+ }
1591
+ }
1592
+ private bindDraggable(): void {
1593
+ if (this.allowDragAndDrop) {
1594
+ const tabHeader: Element = this.element.querySelector('.' + CLS_HEADER);
1595
+ const items: NodeList = tabHeader.querySelectorAll('.' + CLS_TB_ITEM);
1596
+ items.forEach((element: HTMLElement) => {
1597
+ this.initializeDrag(element as HTMLElement);
1598
+ });
1599
+ }
1600
+ }
1601
+ private wireEvents(): void {
1602
+ this.bindDraggable();
1603
+ window.addEventListener('resize', this.resizeContext);
1604
+ EventHandler.add(this.element, 'mouseover', this.hoverHandler, this);
1605
+ EventHandler.add(this.element, 'keydown', this.spaceKeyDown, this);
1606
+ if (!isNOU(this.cntEle)) {
1607
+ this.touchModule = new Touch(this.cntEle, { swipe: this.swipeHandler.bind(this) });
1608
+ }
1609
+ this.keyModule = new KeyboardEvents(this.element, { keyAction: this.keyHandler.bind(this), keyConfigs: this.keyConfigs });
1610
+ this.tabKeyModule = new KeyboardEvents(this.element, {
1611
+ keyAction: this.keyHandler.bind(this),
1612
+ keyConfigs: { openPopup: 'shift+f10', tab: 'tab', shiftTab: 'shift+tab' },
1613
+ eventName: 'keydown'
1614
+ });
1615
+ }
1616
+ private unWireEvents(): void {
1617
+ if (!isNOU(this.keyModule)) {
1618
+ this.keyModule.destroy();
1619
+ }
1620
+ if (!isNOU(this.tabKeyModule)) {
1621
+ this.tabKeyModule.destroy();
1622
+ }
1623
+ if (!isNOU(this.cntEle) && !isNOU(this.touchModule)) {
1624
+ this.touchModule.destroy();
1625
+ this.touchModule = null;
1626
+ }
1627
+ window.removeEventListener('resize', this.resizeContext);
1628
+ EventHandler.remove(this.element, 'mouseover', this.hoverHandler);
1629
+ EventHandler.remove(this.element, 'keydown', this.spaceKeyDown);
1630
+ this.element.classList.remove(CLS_RTL);
1631
+ this.element.classList.remove(CLS_FOCUS);
1632
+ }
1633
+ private clickHandler(args: ClickEventArgs): void {
1634
+ this.element.classList.remove(CLS_FOCUS);
1635
+ const trg: HTEle = <HTEle>args.originalEvent.target;
1636
+ const trgParent: HTEle = <HTEle>closest(trg, '.' + CLS_TB_ITEM);
1637
+ const trgIndex: number = this.getEleIndex(trgParent);
1638
+ if (trg.classList.contains(CLS_ICON_CLOSE)) {
1639
+ this.removeTab(trgIndex);
1640
+ } else if (this.isVertical() && closest(trg, '.' + CLS_HOR_NAV)) {
1641
+ this.showPopup(this.show);
1642
+ } else {
1643
+ this.isPopup = false;
1644
+ if (!isNOU(trgParent) && (trgIndex !== this.selectedItem || trgIndex !== this.prevIndex)) {
1645
+ this.selectTab(trgIndex, args.originalEvent, true);
1646
+ }
1647
+ }
1648
+ }
1649
+ private swipeHandler(e: SwipeEventArgs): void {
1650
+ if (e.velocity < 3 && isNOU(e.originalEvent.changedTouches)) {
1651
+ return;
1652
+ }
1653
+ if (this.isNested) {
1654
+ this.element.setAttribute('data-swipe', 'true');
1655
+ }
1656
+ const nestedTab: HTMLElement = this.element.querySelector('[data-swipe="true"]');
1657
+ if (nestedTab) {
1658
+ nestedTab.removeAttribute('data-swipe');
1659
+ return;
1660
+ }
1661
+ this.isSwipeed = true;
1662
+ if (e.swipeDirection === 'Right' && this.selectedItem !== 0) {
1663
+ for (let k: number = this.selectedItem - 1; k >= 0; k--) {
1664
+ if (!this.tbItem[k].classList.contains(CLS_HIDDEN)) {
1665
+ this.selectTab(k, null, true);
1666
+ break;
1667
+ }
1668
+ }
1669
+ } else if (e.swipeDirection === 'Left' && (this.selectedItem !== selectAll('.' + CLS_TB_ITEM, this.element).length - 1)) {
1670
+ for (let i: number = this.selectedItem + 1; i < this.tbItem.length; i++) {
1671
+ if (!this.tbItem[i].classList.contains(CLS_HIDDEN)) {
1672
+ this.selectTab(i, null, true);
1673
+ break;
1674
+ }
1675
+ }
1676
+ }
1677
+ this.isSwipeed = false;
1678
+ }
1679
+ private spaceKeyDown(e: KeyboardEvent): void {
1680
+ if ((e.keyCode === 32 && e.which === 32) || (e.keyCode === 35 && e.which === 35)) {
1681
+ const clstHead: HTEle = <HTEle>closest(<Element>e.target, '.' + CLS_HEADER);
1682
+ if (!isNOU(clstHead)) {
1683
+ e.preventDefault();
1684
+ }
1685
+ }
1686
+ }
1687
+ private keyHandler(e: KeyboardEventArgs): void {
1688
+ if (this.element.classList.contains(CLS_DISABLE)) {
1689
+ return;
1690
+ }
1691
+ this.element.classList.add(CLS_FOCUS);
1692
+ const trg: HTEle = <HTEle>e.target;
1693
+ const tabHeader: HTMLElement = this.getTabHeader();
1694
+ const actEle: HTEle = <HTEle>select('.' + CLS_ACTIVE, tabHeader);
1695
+ this.popEle = <DomElements>select('.' + CLS_TB_POP, tabHeader);
1696
+ if (!isNOU(this.popEle)) {
1697
+ this.popObj = <Popup>this.popEle.ej2_instances[0];
1698
+ }
1699
+ const item: HTEle = <HTEle>closest(document.activeElement, '.' + CLS_TB_ITEM);
1700
+ const trgParent: HTEle = <HTEle>closest(trg, '.' + CLS_TB_ITEM);
1701
+ switch (e.action) {
1702
+ case 'space':
1703
+ case 'enter':
1704
+ if (trg.parentElement.classList.contains(CLS_DISABLE)) {
1705
+ return;
1706
+ }
1707
+ if (e.action === 'enter' && trg.classList.contains('e-hor-nav')) {
1708
+ this.showPopup(this.show);
1709
+ break;
1710
+ }
1711
+ this.keyPressed(trg);
1712
+ break;
1713
+ case 'tab':
1714
+ case 'shiftTab':
1715
+ if (trg.classList.contains(CLS_WRAP)
1716
+ && (<HTEle>closest(trg, '.' + CLS_TB_ITEM)).classList.contains(CLS_ACTIVE) === false) {
1717
+ trg.setAttribute('tabindex', '-1');
1718
+ }
1719
+ if (this.popObj && isVisible(this.popObj.element)) {
1720
+ this.popObj.hide(this.hide);
1721
+ }
1722
+ actEle.children.item(0).setAttribute('tabindex', '0');
1723
+ break;
1724
+ case 'moveLeft':
1725
+ case 'moveRight':
1726
+ if (!isNOU(item)) {
1727
+ this.refreshItemVisibility(item);
1728
+ }
1729
+ break;
1730
+ case 'openPopup':
1731
+ e.preventDefault();
1732
+ if (!isNOU(this.popEle) && this.popEle.classList.contains(CLS_POPUP_CLOSE)) {
1733
+ this.popObj.show(this.show);
1734
+ }
1735
+ break;
1736
+ case 'delete':
1737
+ if (this.showCloseButton === true && !isNOU(trgParent)) {
1738
+ const nxtSib: HTEle = <HTEle>trgParent.nextSibling;
1739
+ if (!isNOU(nxtSib) && nxtSib.classList.contains(CLS_TB_ITEM)) {
1740
+ (<HTEle>nxtSib.firstElementChild).focus();
1741
+ }
1742
+ this.removeTab(this.getEleIndex(trgParent));
1743
+ }
1744
+ this.setActiveBorder();
1745
+ break;
1746
+ }
1747
+ }
1748
+ /**
1749
+ * Refresh the active tab border
1750
+ *
1751
+ * @returns {void}
1752
+ * @private
1753
+ */
1754
+ public refreshActiveTabBorder(): void {
1755
+ const activeEle: Element = select('.' + CLS_TB_ITEM + '.' + CLS_TB_POPUP + '.' + CLS_ACTIVE, this.element);
1756
+ if (!isNOU(activeEle) && this.reorderActiveTab) {
1757
+ this.select(this.getEleIndex(<HTEle>activeEle));
1758
+ }
1759
+ this.refreshActiveBorder();
1760
+ }
1761
+ private refreshItemVisibility(target: HTEle): void {
1762
+ const scrCnt: HTEle = <HTEle>select('.' + this.scrCntClass, this.tbItems);
1763
+ if (!this.isVertical() && !isNOU(scrCnt)) {
1764
+ const scrBar: HTEle = <HTEle>select('.e-hscroll-bar', this.tbItems);
1765
+ const scrStart: number = scrBar.scrollLeft;
1766
+ const scrEnd: number = scrStart + scrBar.offsetWidth;
1767
+ const eleStart: number = target.offsetLeft;
1768
+ const eleWidth: number = target.offsetWidth;
1769
+ const eleEnd: number = target.offsetLeft + target.offsetWidth;
1770
+ if ((scrStart < eleStart) && (scrEnd < eleEnd)) {
1771
+ const eleViewRange: number = scrEnd - eleStart;
1772
+ scrBar.scrollLeft = scrStart + (eleWidth - eleViewRange);
1773
+ } else {
1774
+ if ((scrStart > eleStart) && (scrEnd > eleEnd)) {
1775
+ const eleViewRange: number = eleEnd - scrStart;
1776
+ scrBar.scrollLeft = scrStart - (eleWidth - eleViewRange);
1777
+ }
1778
+ }
1779
+ } else {
1780
+ return;
1781
+ }
1782
+ }
1783
+ private hoverHandler(e: MouseEventArgs): void {
1784
+ const trg: HTEle = <HTEle>e.target;
1785
+ if (!isNOU(trg.classList) && trg.classList.contains(CLS_ICON_CLOSE)) {
1786
+ trg.setAttribute('title', new L10n('tab', { closeButtonTitle: this.title }, this.locale).getConstant('closeButtonTitle'));
1787
+ }
1788
+ }
1789
+ private evalOnPropertyChangeItems(newProp: TabModel, oldProp: TabModel): void {
1790
+ if (!(newProp.items instanceof Array && oldProp.items instanceof Array)) {
1791
+ const changedProp: Object[] = Object.keys(newProp.items);
1792
+ for (let i: number = 0; i < changedProp.length; i++) {
1793
+ const index: number = parseInt(Object.keys(newProp.items)[i], 10);
1794
+ const properties: string[] = Object.keys(newProp.items[index]);
1795
+ for (let j: number = 0; j < properties.length; j++) {
1796
+ const oldVal: Str = Object(oldProp.items[index])[properties[j]];
1797
+ const newVal: Str | Object = Object(newProp.items[index])[properties[j]];
1798
+ const hdr: HTEle = <HTEle>this.element.querySelectorAll('.' + CLS_TB_ITEM)[index];
1799
+ let itemIndex: number;
1800
+ if (hdr && !isNOU(hdr.id) && hdr.id !== '') {
1801
+ const num: number = (hdr.id.lastIndexOf('_'));
1802
+ itemIndex = parseInt(hdr.id.substring(num + 1), 10);
1803
+ } else {
1804
+ itemIndex = index;
1805
+ }
1806
+ const hdrItem: HTEle = <HTEle>select('.' + CLS_TB_ITEMS + ' #' + CLS_ITEM + this.tabId + '_' + itemIndex, this.element);
1807
+ const cntItem: HTEle = <HTEle>select('.' + CLS_CONTENT + ' #' + CLS_CONTENT + this.tabId + '_' + itemIndex, this.element);
1808
+ if (properties[j] === 'header' || properties[j] === 'headerTemplate') {
1809
+ const icon: Str | Object = (isNOU(this.items[index].header) ||
1810
+ isNOU(this.items[index].header.iconCss)) ? '' : this.items[index].header.iconCss;
1811
+ const textVal: Str | Object = this.items[index].headerTemplate || this.items[index].header.text;
1812
+ if ((textVal === '') && (icon === '')) {
1813
+ this.removeTab(index);
1814
+ } else {
1815
+ this.tbId = hdr.id;
1816
+ const arr: Object[] = [];
1817
+ arr.push(<TabItemModel>this.items[index]);
1818
+ this.items.splice(index, 1);
1819
+ this.itemIndexArray.splice(index, 1);
1820
+ this.tbObj.items.splice(index, 1);
1821
+ const isHiddenEle: boolean = hdrItem.classList.contains(CLS_HIDDEN);
1822
+ detach(hdrItem);
1823
+ this.isReplace = true;
1824
+ this.addTab(arr, index);
1825
+ if (isHiddenEle) {
1826
+ this.hideTab(index);
1827
+ }
1828
+ this.isReplace = false;
1829
+ }
1830
+ }
1831
+ if (properties[j] === 'content' && !isNOU(cntItem)) {
1832
+ const strVal: boolean = typeof newVal === 'string' || isNOU((<HTEle>newVal).innerHTML);
1833
+ if (strVal && ((<Str>newVal)[0] === '.' || (<Str>newVal)[0] === '#') && (<Str>newVal).length) {
1834
+ const eleVal: HTEle = <HTEle>document.querySelector(<Str>newVal);
1835
+ cntItem.appendChild(eleVal);
1836
+ eleVal.style.display = '';
1837
+ } else if (newVal === '' && oldVal[0] === '#') {
1838
+ (<HTEle>document.body.appendChild(this.element.querySelector(oldVal))).style.display = 'none';
1839
+ cntItem.innerHTML = <Str>newVal;
1840
+ } else if ((this as any).isReact) {
1841
+ cntItem.innerHTML = '';
1842
+ this.templateCompile(cntItem, <Str>newVal, index);
1843
+ } else if (typeof newVal !== 'function') {
1844
+ cntItem.innerHTML = <Str>newVal;
1845
+ }
1846
+ }
1847
+ if (properties[j] === 'cssClass') {
1848
+ if (!isNOU(hdrItem)) {
1849
+ hdrItem.classList.remove(oldVal);
1850
+ hdrItem.classList.add(<Str>newVal);
1851
+ }
1852
+ if (!isNOU(cntItem)) {
1853
+ cntItem.classList.remove(oldVal);
1854
+ cntItem.classList.add(<Str>newVal);
1855
+ }
1856
+ }
1857
+ if (properties[j] === 'disabled') {
1858
+ this.enableTab(index, ((newVal === true) ? false : true));
1859
+ }
1860
+ if (properties[j] === 'visible') {
1861
+ this.hideTab(index, ((newVal === true) ? false : true));
1862
+ }
1863
+ }
1864
+ }
1865
+ } else {
1866
+ this.lastIndex = 0;
1867
+ if (isNOU(this.tbObj)) {
1868
+ this.reRenderItems();
1869
+ } else {
1870
+ if ((this as any).isReact || (this as any).isAngular) {
1871
+ this.clearTemplate();
1872
+ }
1873
+ this.setItems(<TabItemModel[]>newProp.items);
1874
+ if (this.templateEle.length > 0) {
1875
+ this.expTemplateContent();
1876
+ }
1877
+ this.templateEle = [];
1878
+ const selectElement: HTEle = <HTEle>select('.' + CLS_TAB + ' > .' + CLS_CONTENT, this.element);
1879
+ while (selectElement.firstElementChild) {
1880
+ detach(selectElement.firstElementChild);
1881
+ }
1882
+ this.select(this.selectedItem);
1883
+ this.draggableItems = [];
1884
+ this.bindDraggable();
1885
+ }
1886
+ }
1887
+ }
1888
+
1889
+ private initializeDrag(target: HTEle): void {
1890
+ let dragObj: Draggable = new Draggable(target, {
1891
+ dragArea: this.dragArea,
1892
+ dragTarget: '.' + CLS_TB_ITEM,
1893
+ clone: true,
1894
+ helper: this.helper.bind(this),
1895
+ dragStart: this.itemDragStart.bind(this),
1896
+ drag: (e: DragArgs) => {
1897
+ let dragIndex: number = this.getEleIndex(this.dragItem);
1898
+ let dropIndex: number;
1899
+ let dropItem: HTMLElement;
1900
+ let dragArgs: DragEventArgs = {
1901
+ draggedItem: <HTMLElement>this.dragItem,
1902
+ event: e.event,
1903
+ target: e.target,
1904
+ droppedItem: <HTMLElement>e.target.closest('.' + CLS_TB_ITEM),
1905
+ clonedElement: this.cloneElement,
1906
+ index: dragIndex
1907
+ };
1908
+ if (!isNOU(e.target.closest('.' + CLS_TAB)) && !e.target.closest('.' + CLS_TAB).isEqualNode(this.element) &&
1909
+ this.dragArea !== '.' + CLS_HEADER) {
1910
+ this.trigger('dragging', dragArgs);
1911
+ } else {
1912
+ if (!(e.target.closest(this.dragArea)) && this.overflowMode !== 'Popup') {
1913
+ document.body.style.cursor = 'not-allowed';
1914
+ addClass([this.cloneElement], CLS_HIDDEN);
1915
+ if (this.dragItem.classList.contains(CLS_HIDDEN)) {
1916
+ removeClass([this.dragItem], CLS_HIDDEN);
1917
+ }
1918
+ (<HTEle>this.dragItem.querySelector('.' + CLS_WRAP)).style.visibility = 'visible';
1919
+ } else {
1920
+ document.body.style.cursor = '';
1921
+ (<HTEle>this.dragItem.querySelector('.' + CLS_WRAP)).style.visibility = 'hidden';
1922
+ if (this.cloneElement.classList.contains(CLS_HIDDEN)) {
1923
+ removeClass([this.cloneElement], CLS_HIDDEN);
1924
+ }
1925
+ }
1926
+ if (this.overflowMode === 'Scrollable' && !isNOU(this.element.querySelector('.e-hscroll'))) {
1927
+ let scrollRightNavEle: HTMLElement = this.element.querySelector('.e-scroll-right-nav');
1928
+ let scrollLeftNavEle: HTMLElement = this.element.querySelector('.e-scroll-left-nav');
1929
+ let hscrollBar: HTMLElement = this.element.querySelector('.e-hscroll-bar');
1930
+ if (!isNOU(scrollRightNavEle) && Math.abs((scrollRightNavEle.offsetWidth / 2) +
1931
+ scrollRightNavEle.offsetLeft) > this.cloneElement.offsetLeft + this.cloneElement.offsetWidth) {
1932
+ hscrollBar.scrollLeft -= 10;
1933
+ }
1934
+ if (!isNOU(scrollLeftNavEle) && Math.abs((scrollLeftNavEle.offsetLeft + scrollLeftNavEle.offsetWidth) -
1935
+ this.cloneElement.offsetLeft) > (scrollLeftNavEle.offsetWidth / 2)) {
1936
+ hscrollBar.scrollLeft += 10;
1937
+ }
1938
+ }
1939
+ this.cloneElement.style.pointerEvents = 'none';
1940
+ dropItem = <HTMLElement>closest(e.target, '.' + CLS_TB_ITEM + '.e-draggable');
1941
+ let scrollContentWidth: number = 0;
1942
+ if (this.overflowMode === 'Scrollable' && !isNOU(this.element.querySelector('.e-hscroll'))) {
1943
+ scrollContentWidth = (<HTMLElement>this.element.querySelector('.e-hscroll-content')).offsetWidth;
1944
+ }
1945
+ if (dropItem != null && !dropItem.isSameNode(this.dragItem) &&
1946
+ dropItem.closest('.' + CLS_TAB).isSameNode(this.dragItem.closest('.' + CLS_TAB))) {
1947
+ dropIndex = this.getEleIndex(dropItem);
1948
+ if (dropIndex < dragIndex &&
1949
+ (Math.abs((dropItem.offsetLeft + dropItem.offsetWidth) -
1950
+ this.cloneElement.offsetLeft) > (dropItem.offsetWidth / 2))) {
1951
+ this.dragAction(dropItem, dragIndex, dropIndex);
1952
+ }
1953
+ if (dropIndex > dragIndex &&
1954
+ (Math.abs(dropItem.offsetWidth / 2) + dropItem.offsetLeft -
1955
+ scrollContentWidth) < this.cloneElement.offsetLeft + this.cloneElement.offsetWidth) {
1956
+ this.dragAction(dropItem, dragIndex, dropIndex);
1957
+ }
1958
+ }
1959
+ this.droppedIndex = this.getEleIndex(this.dragItem);
1960
+ this.trigger('dragging', dragArgs);
1961
+ }
1962
+ },
1963
+ dragStop: this.itemDragStop.bind(this)
1964
+ });
1965
+ this.draggableItems.push(dragObj);
1966
+ }
1967
+
1968
+ private helper(e: { sender: MouseEvent & TouchEvent, element: HTMLElement }): HTMLElement {
1969
+ this.cloneElement = this.createElement('div');
1970
+ if (e.element) {
1971
+ this.cloneElement = <HTMLElement>(e.element.cloneNode(true));
1972
+ addClass([this.cloneElement], 'e-tab-clone-element');
1973
+ if (this.element.querySelector('.' + CLS_HEADER).classList.contains(CLS_CLOSE_SHOW)) {
1974
+ addClass([this.cloneElement], CLS_CLOSE_SHOW);
1975
+ }
1976
+ removeClass([this.cloneElement.querySelector('.' + CLS_WRAP)], 'e-ripple');
1977
+ if (!isNOU(this.cloneElement.querySelector('.e-ripple-element'))) {
1978
+ remove(this.cloneElement.querySelector('.e-ripple-element'));
1979
+ }
1980
+ document.body.appendChild(this.cloneElement);
1981
+ }
1982
+ return this.cloneElement;
1983
+ }
1984
+
1985
+ private itemDragStart(e: DragArgs): void {
1986
+ this.draggingItems = this.items.map((x: TabItemModel) => x);
1987
+ this.dragItem = e.element;
1988
+ let dragArgs: DragEventArgs = {
1989
+ draggedItem: e.element,
1990
+ event: e.event,
1991
+ target: e.target,
1992
+ droppedItem: null,
1993
+ index: this.getEleIndex(this.dragItem),
1994
+ clonedElement: this.cloneElement,
1995
+ cancel: false
1996
+ };
1997
+ this.trigger('onDragStart', dragArgs, (tabitemDragArgs: DragEventArgs) => {
1998
+ if (tabitemDragArgs.cancel) {
1999
+ detach(this.cloneElement);
2000
+ } else {
2001
+ this.removeActiveClass();
2002
+ addClass([this.tbItems.querySelector('.' + CLS_INDICATOR)], CLS_HIDDEN);
2003
+ (<HTEle>this.dragItem.querySelector('.' + CLS_WRAP)).style.visibility = 'hidden';
2004
+ }
2005
+ });
2006
+ }
2007
+
2008
+ private dragAction(dropItem: HTMLElement, dragsIndex: number, dropIndex: number): void {
2009
+ if (this.items.length > 0) {
2010
+ let item: TabItemModel = this.draggingItems[dragsIndex];
2011
+ this.draggingItems.splice(dragsIndex, 1);
2012
+ this.draggingItems.splice(dropIndex, 0, item);
2013
+ }
2014
+ if (this.overflowMode === 'MultiRow') {
2015
+ dropItem.parentNode.insertBefore(this.dragItem, dropItem.nextElementSibling);
2016
+ }
2017
+ if (dragsIndex > dropIndex) {
2018
+ if (!(this.dragItem.parentElement).isSameNode(dropItem.parentElement)) {
2019
+ if (this.overflowMode === 'Extended') {
2020
+ if (dropItem.isSameNode(dropItem.parentElement.lastChild)) {
2021
+ let popupContainer: Node = this.dragItem.parentNode;
2022
+ dropItem.parentNode.insertBefore(this.dragItem, dropItem);
2023
+ popupContainer.insertBefore(dropItem.parentElement.lastChild, popupContainer.childNodes[0]);
2024
+ } else {
2025
+ this.dragItem.parentNode.insertBefore(
2026
+ (dropItem.parentElement.lastChild), this.dragItem.parentElement.childNodes[0]);
2027
+ dropItem.parentNode.insertBefore(this.dragItem, dropItem);
2028
+ }
2029
+ } else {
2030
+ let lastEle: HTMLElement = <HTEle>(dropItem.parentElement).lastChild;
2031
+ if (dropItem.isSameNode(lastEle)) {
2032
+ let popupContainer: Node = <HTEle>this.dragItem.parentNode;
2033
+ dropItem.parentNode.insertBefore(this.dragItem, dropItem);
2034
+ popupContainer.insertBefore(lastEle, popupContainer.childNodes[0]);
2035
+ } else {
2036
+ this.dragItem.parentNode.insertBefore(
2037
+ (dropItem.parentElement).lastChild, this.dragItem.parentElement.childNodes[0]);
2038
+ dropItem.parentNode.insertBefore(this.dragItem, dropItem);
2039
+ }
2040
+ }
2041
+ } else {
2042
+ this.dragItem.parentNode.insertBefore(this.dragItem, dropItem);
2043
+ }
2044
+ }
2045
+ if (dragsIndex < dropIndex) {
2046
+ if (!(this.dragItem.parentElement).isSameNode(dropItem.parentElement)) {
2047
+ if (this.overflowMode === 'Extended') {
2048
+ this.dragItem.parentElement.appendChild(dropItem.parentElement.firstElementChild);
2049
+ dropItem.parentNode.insertBefore(this.dragItem, dropItem.nextSibling);
2050
+ } else {
2051
+ this.dragItem.parentNode.insertBefore(
2052
+ (dropItem.parentElement).lastChild, this.dragItem.parentElement.childNodes[0]);
2053
+ dropItem.parentNode.insertBefore(this.dragItem, dropItem);
2054
+ }
2055
+ } else {
2056
+ this.dragItem.parentNode.insertBefore(dropItem, this.dragItem);
2057
+ }
2058
+ }
2059
+ }
2060
+
2061
+ private itemDragStop(e: DropEventArgs): void {
2062
+ detach(this.cloneElement);
2063
+ this.cloneElement = null;
2064
+ (<HTEle>this.dragItem.querySelector('.' + CLS_WRAP)).style.visibility = 'visible';
2065
+ document.body.style.cursor = '';
2066
+ let dragStopArgs: DragEventArgs = {
2067
+ draggedItem: <HTEle>this.dragItem,
2068
+ event: e.event,
2069
+ target: e.target,
2070
+ droppedItem: this.tbItem[this.droppedIndex],
2071
+ clonedElement: null,
2072
+ index: this.droppedIndex,
2073
+ cancel: false
2074
+ };
2075
+ this.trigger('dragged', dragStopArgs, (tabItemDropArgs: DragEventArgs) => {
2076
+ if (tabItemDropArgs.cancel) {
2077
+ this.refresh();
2078
+ } else {
2079
+ if (this.items.length > 0 && this.draggingItems.length > 0) {
2080
+ this.items = this.draggingItems;
2081
+ this.selectedItem = this.droppedIndex;
2082
+ this.refresh();
2083
+ } else {
2084
+ (<HTEle>this.dragItem.querySelector('.' + CLS_WRAP)).style.visibility = '';
2085
+ removeClass([<HTEle>this.tbItems.querySelector('.' + CLS_INDICATOR)], CLS_HIDDEN);
2086
+ this.selectTab(this.droppedIndex, null, true);
2087
+ }
2088
+ }
2089
+ });
2090
+ this.dragItem = null;
2091
+ }
2092
+
2093
+ /**
2094
+ * Enables or disables the specified Tab item. On passing value as `false`, the item will be disabled.
2095
+ *
2096
+ * @param {number} index - Index value of target Tab item.
2097
+ * @param {boolean} value - Boolean value that determines whether the command should be enabled or disabled.
2098
+ * By default, isEnable is true.
2099
+ * @returns {void}.
2100
+ */
2101
+ public enableTab(index: number, value: boolean): void {
2102
+ const tbItems: HTEle = selectAll('.' + CLS_TB_ITEM, this.element)[index];
2103
+ if (isNOU(tbItems)) {
2104
+ return;
2105
+ }
2106
+ if (value === true) {
2107
+ tbItems.classList.remove(CLS_DISABLE, CLS_OVERLAY);
2108
+ (<HTEle>tbItems.firstElementChild).setAttribute('tabindex', '-1');
2109
+ } else {
2110
+ tbItems.classList.add(CLS_DISABLE, CLS_OVERLAY);
2111
+ (<HTEle>tbItems.firstElementChild).removeAttribute('tabindex');
2112
+ if (tbItems.classList.contains(CLS_ACTIVE)) {
2113
+ this.select(index + 1);
2114
+ }
2115
+ }
2116
+ if (!isNOU(this.items[index])) {
2117
+ this.items[index].disabled = !value;
2118
+ this.dataBind();
2119
+ }
2120
+ tbItems.setAttribute('aria-disabled', (value === true) ? 'false' : 'true');
2121
+ }
2122
+ /**
2123
+ * Adds new items to the Tab that accepts an array as Tab items.
2124
+ *
2125
+ * @param {TabItemModel[]} items - An array of item that is added to the Tab.
2126
+ * @param {number} index - Number value that determines where the items to be added. By default, index is 0.
2127
+ * @returns {void}.
2128
+ */
2129
+ public addTab(items: TabItemModel[], index?: number): void {
2130
+ const addArgs: AddEventArgs = { addedItems: items, cancel: false };
2131
+ if (!this.isReplace) {
2132
+ this.trigger('adding', addArgs, (tabAddingArgs: AddEventArgs) => {
2133
+ if (!tabAddingArgs.cancel) {
2134
+ this.addingTabContent(items, index);
2135
+ }
2136
+ });
2137
+ } else {
2138
+ this.addingTabContent(items, index);
2139
+ }
2140
+ if ((this as any).isReact) {
2141
+ this.renderReactTemplates();
2142
+ }
2143
+ }
2144
+ private addingTabContent(items: TabItemModel[], index?: number): void {
2145
+ let lastEleIndex: number = 0;
2146
+ this.hdrEle = <HTEle>select('.' + CLS_HEADER, this.element);
2147
+ if (isNOU(this.hdrEle)) {
2148
+ this.items = items;
2149
+ this.reRenderItems();
2150
+ } else {
2151
+ const itemsCount: number = selectAll('.e-tab-header .' + CLS_TB_ITEM, this.element).length;
2152
+ if (itemsCount !== 0) {
2153
+ lastEleIndex = this.lastIndex + 1;
2154
+ }
2155
+ if (isNOU(index)) {
2156
+ index = itemsCount - 1;
2157
+ }
2158
+ if (itemsCount < index || index < 0 || isNaN(index)) {
2159
+ return;
2160
+ }
2161
+ if (itemsCount === 0 && !isNOU(this.hdrEle)) {
2162
+ this.hdrEle.style.display = '';
2163
+ }
2164
+ if (!isNOU(this.bdrLine)) {
2165
+ this.bdrLine.classList.add(CLS_HIDDEN);
2166
+ }
2167
+ this.tbItems = <HTEle>select('.' + CLS_TB_ITEMS, this.getTabHeader());
2168
+ this.isAdd = true;
2169
+ const tabItems: object[] = this.parseObject(items, index);
2170
+ this.isAdd = false;
2171
+ let i: number = 0;
2172
+ let textValue: string | HTEle;
2173
+ items.forEach((item: TabItemModel, place: number) => {
2174
+ textValue = item.headerTemplate || item.header.text;
2175
+ if (!(isNOU(item.headerTemplate || item.header) || isNOU(textValue) ||
2176
+ ((<string>textValue).length === 0) && !isNOU(item.header) && isNOU(item.header.iconCss))) {
2177
+ this.items.splice((index + i), 0, item);
2178
+ i++;
2179
+ }
2180
+ if (this.isTemplate && !isNOU(item.header) && !isNOU(item.header.text)) {
2181
+ const no: number = lastEleIndex + place;
2182
+ const ele: HTEle = this.createElement('div', {
2183
+ id: CLS_CONTENT + this.tabId + '_' + no, className: CLS_ITEM,
2184
+ attrs: { role: 'tabpanel', 'aria-labelledby': CLS_ITEM + '_' + no }
2185
+ });
2186
+ this.cntEle.insertBefore(ele, this.cntEle.children[(index + place)]);
2187
+ const eleTrg: HTEle = this.getTrgContent(this.cntEle, no.toString());
2188
+ this.getContent(eleTrg, item.content, 'render', index);
2189
+ }
2190
+ });
2191
+ this.tbObj.addItems(tabItems, index);
2192
+ if (!this.isReplace) {
2193
+ this.trigger('added', { addedItems: items });
2194
+ }
2195
+ if (this.selectedItem === index) {
2196
+ this.select(index);
2197
+ } else {
2198
+ this.setActiveBorder();
2199
+ }
2200
+ this.bindDraggable();
2201
+ }
2202
+ }
2203
+ /**
2204
+ * Removes the items in the Tab from the specified index.
2205
+ *
2206
+ * @param {number} index - Index of target item that is going to be removed.
2207
+ * @returns {void}.
2208
+ */
2209
+ public removeTab(index: number): void {
2210
+ const trg: HTEle = selectAll('.' + CLS_TB_ITEM, this.element)[index];
2211
+ if (isNOU(trg)) {
2212
+ return;
2213
+ }
2214
+ const removeArgs: RemoveEventArgs = { removedItem: trg, removedIndex: index, cancel: false };
2215
+ this.trigger('removing', removeArgs, (tabRemovingArgs: RemoveEventArgs) => {
2216
+ if (!tabRemovingArgs.cancel) {
2217
+ this.tbObj.removeItems(index);
2218
+ if (this.allowDragAndDrop && (index !== Array.prototype.indexOf.call(this.itemIndexArray, trg.id))) {
2219
+ index = Array.prototype.indexOf.call(this.itemIndexArray, trg.id);
2220
+ }
2221
+ this.items.splice(index, 1);
2222
+ this.itemIndexArray.splice(index, 1);
2223
+ this.refreshActiveBorder();
2224
+ const cntTrg: HTEle =
2225
+ <HTEle>select('#' + CLS_CONTENT + this.tabId + '_' + this.extIndex(trg.id), select('.' + CLS_CONTENT, this.element));
2226
+ if (!isNOU(cntTrg)) {
2227
+ detach(cntTrg);
2228
+ }
2229
+ this.trigger('removed', tabRemovingArgs);
2230
+ if (this.draggableItems && this.draggableItems.length > 0) {
2231
+ this.draggableItems[index].destroy();
2232
+ this.draggableItems[index] = null;
2233
+ this.draggableItems.splice(index, 1);
2234
+ }
2235
+ if (trg.classList.contains(CLS_ACTIVE)) {
2236
+ index = (index > selectAll('.' + CLS_TB_ITEM + ':not(.' + CLS_TB_POPUP + ')', this.element).length - 1) ? index - 1 : index;
2237
+ this.enableAnimation = false;
2238
+ this.selectedItem = index;
2239
+ this.select(index);
2240
+ } else if (index !== this.selectedItem) {
2241
+ if (index < this.selectedItem) {
2242
+ index = this.itemIndexArray.indexOf(this.tbItem[this.selectedItem].id);
2243
+ this.setProperties({ selectedItem: index > -1 ? index : this.selectedItem }, true);
2244
+ this.prevIndex = this.selectedItem;
2245
+ }
2246
+ this.tbItem = selectAll('.' + CLS_TB_ITEM, this.getTabHeader());
2247
+ }
2248
+ if (selectAll('.' + CLS_TB_ITEM, this.element).length === 0) {
2249
+ this.hdrEle.style.display = 'none';
2250
+ }
2251
+ this.enableAnimation = true;
2252
+ }
2253
+ });
2254
+ }
2255
+ /**
2256
+ * Shows or hides the Tab that is in the specified index.
2257
+ *
2258
+ * @param {number} index - Index value of target item.
2259
+ * @param {boolean} value - Based on this Boolean value, item will be hide (false) or show (true). By default, value is true.
2260
+ * @returns {void}.
2261
+ */
2262
+ public hideTab(index: number, value?: boolean): void {
2263
+ let items: HTMLElement[];
2264
+ const item: HTEle = selectAll('.' + CLS_TB_ITEM, this.element)[index];
2265
+ if (isNOU(item)) {
2266
+ return;
2267
+ }
2268
+ if (isNOU(value)) {
2269
+ value = true;
2270
+ }
2271
+ this.bdrLine.classList.add(CLS_HIDDEN);
2272
+ if (value === true) {
2273
+ item.classList.add(CLS_HIDDEN);
2274
+ items = selectAll('.' + CLS_TB_ITEM + ':not(.' + CLS_HIDDEN + ')', this.tbItems);
2275
+ if (items.length !== 0 && item.classList.contains(CLS_ACTIVE)) {
2276
+ if (index !== 0) {
2277
+ for (let i: number = index - 1; i >= 0; i--) {
2278
+ if (!this.tbItem[i].classList.contains(CLS_HIDDEN)) {
2279
+ this.select(i);
2280
+ break;
2281
+ } else if (i === 0) {
2282
+ for (let k: number = index + 1; k < this.tbItem.length; k++) {
2283
+ if (!this.tbItem[k].classList.contains(CLS_HIDDEN)) {
2284
+ this.select(k);
2285
+ break;
2286
+ }
2287
+ }
2288
+ }
2289
+ }
2290
+ } else {
2291
+ for (let k: number = index + 1; k < this.tbItem.length; k++) {
2292
+ if (!this.tbItem[k].classList.contains(CLS_HIDDEN)) {
2293
+ this.select(k);
2294
+ break;
2295
+ }
2296
+ }
2297
+ }
2298
+ } else if (items.length === 0) {
2299
+ this.element.classList.add(CLS_HIDDEN);
2300
+ }
2301
+ } else {
2302
+ this.element.classList.remove(CLS_HIDDEN);
2303
+ items = selectAll('.' + CLS_TB_ITEM + ':not(.' + CLS_HIDDEN + ')', this.tbItems);
2304
+ item.classList.remove(CLS_HIDDEN);
2305
+ if (items.length === 0) {
2306
+ this.select(index);
2307
+ }
2308
+ }
2309
+ this.setActiveBorder();
2310
+ item.setAttribute('aria-hidden', '' + value);
2311
+ if (this.overflowMode === 'Popup' && this.tbObj) {
2312
+ this.tbObj.refreshOverflow();
2313
+ }
2314
+ }
2315
+
2316
+ private selectTab(args: number | HTEle, event: Event = null, isInteracted: boolean = false): void {
2317
+ this.isInteracted = isInteracted;
2318
+ this.select(args, event);
2319
+ }
2320
+
2321
+ /**
2322
+ * Specifies the index or HTMLElement to select an item from the Tab.
2323
+ *
2324
+ * @param {number | HTMLElement} args - Index or DOM element is used for selecting an item from the Tab.
2325
+ * @param {Event} event - An event which takes place in DOM.
2326
+ * @returns {void}
2327
+ */
2328
+
2329
+ public select(args: number | HTEle, event?: Event): void {
2330
+ const tabHeader: HTMLElement = this.getTabHeader();
2331
+ this.tbItems = <HTEle>select('.' + CLS_TB_ITEMS, tabHeader);
2332
+ this.tbItem = selectAll('.' + CLS_TB_ITEM, tabHeader);
2333
+ this.content = <HTEle>select('.' + CLS_CONTENT, this.element);
2334
+ this.prevItem = this.tbItem[this.prevIndex];
2335
+ if (isNOU(this.selectedItem) || (this.selectedItem < 0) || (this.tbItem.length <= this.selectedItem) || isNaN(this.selectedItem)) {
2336
+ this.selectedItem = 0;
2337
+ } else {
2338
+ this.selectedID = this.extIndex(this.tbItem[this.selectedItem].id);
2339
+ }
2340
+ const trg: HTEle = this.tbItem[args as number];
2341
+ if (isNOU(trg)) {
2342
+ this.selectedID = '0';
2343
+ } else {
2344
+ this.selectingID = this.extIndex(trg.id);
2345
+ }
2346
+ if (!isNOU(this.prevItem) && !this.prevItem.classList.contains(CLS_DISABLE)) {
2347
+ this.prevItem.children.item(0).setAttribute('tabindex', '-1');
2348
+ }
2349
+ const eventArg: SelectingEventArgs = {
2350
+ event: event,
2351
+ previousItem: this.prevItem,
2352
+ previousIndex: this.prevIndex,
2353
+ selectedItem: this.tbItem[this.selectedItem],
2354
+ selectedIndex: this.selectedItem,
2355
+ selectedContent: !isNOU(this.content) ?
2356
+ <HTEle>select('#' + CLS_CONTENT + this.tabId + '_' + this.selectedID, this.content) : null,
2357
+ selectingItem: trg,
2358
+ selectingIndex: args as number,
2359
+ selectingContent: !isNOU(this.content) ?
2360
+ <HTEle>select('#' + CLS_CONTENT + this.tabId + '_' + this.selectingID, this.content) : null,
2361
+ isSwiped: this.isSwipeed,
2362
+ isInteracted: this.isInteracted,
2363
+ cancel: false
2364
+ };
2365
+ if (!this.initRender) {
2366
+ this.trigger('selecting', eventArg, (selectArgs: SelectingEventArgs) => {
2367
+ if (!selectArgs.cancel) {
2368
+ this.selectingContent(args, this.isInteracted);
2369
+ }
2370
+ });
2371
+ } else {
2372
+ this.selectingContent(args, this.isInteracted);
2373
+ }
2374
+ this.isInteracted = false;
2375
+ }
2376
+
2377
+ private selectingContent(args: number | HTEle, isInteracted?: boolean): void {
2378
+ if (typeof args === 'number') {
2379
+ if (!isNOU(this.tbItem[args]) && (this.tbItem[<number>args].classList.contains(CLS_DISABLE) ||
2380
+ this.tbItem[<number>args].classList.contains(CLS_HIDDEN))) {
2381
+ for (let i: number = <number>args + 1; i < this.items.length; i++) {
2382
+ if (this.items[i].disabled === false && this.items[i].visible === true) {
2383
+ args = i; break;
2384
+ } else {
2385
+ args = 0;
2386
+ }
2387
+ }
2388
+ }
2389
+ if (this.tbItem.length > args && args >= 0 && !isNaN(args)) {
2390
+ this.prevIndex = this.selectedItem;
2391
+ this.prevItem = this.tbItem[this.prevIndex];
2392
+ if (this.tbItem[args].classList.contains(CLS_TB_POPUP) && this.reorderActiveTab) {
2393
+ this.setActive(this.popupHandler(this.tbItem[args]), null, isInteracted);
2394
+ if ((!isNOU(this.items) && this.items.length > 0) && this.allowDragAndDrop) {
2395
+ this.tbItem = selectAll('.' + CLS_TB_ITEMS + ' .' + CLS_TB_ITEM, this.hdrEle);
2396
+ let item: TabItemModel = this.items[args];
2397
+ this.items.splice(args, 1);
2398
+ this.items.splice(this.tbItem.length - 1, 0, item);
2399
+ }
2400
+ } else {
2401
+ this.setActive(args, null, isInteracted);
2402
+ }
2403
+ } else {
2404
+ this.setActive(0, null, isInteracted);
2405
+ }
2406
+ } else if (args instanceof (HTMLElement)) {
2407
+ this.setActive(this.getEleIndex(args), null, isInteracted);
2408
+ }
2409
+ }
2410
+ /**
2411
+ * Gets the item index from the Tab.
2412
+ *
2413
+ * @param {string} tabItemId - Item ID is used for getting index from the Tab.
2414
+ * @returns {number} - It returns item index.
2415
+ */
2416
+ public getItemIndex(tabItemId: string): number {
2417
+ let tabIndex: number;
2418
+ for (let i: number = 0; i < this.tbItem.length; i++) {
2419
+ const value: string = this.tbItem[i].getAttribute('data-id');
2420
+ if (tabItemId === value) {
2421
+ tabIndex = i;
2422
+ break;
2423
+ }
2424
+ }
2425
+ return tabIndex;
2426
+ }
2427
+ /**
2428
+ * Specifies the value to disable/enable the Tab component.
2429
+ * When set to `true`, the component will be disabled.
2430
+ *
2431
+ * @param {boolean} value - Based on this Boolean value, Tab will be enabled (false) or disabled (true).
2432
+ * @returns {void}.
2433
+ */
2434
+ public disable(value: boolean): void {
2435
+ this.setCssClass(this.element, CLS_DISABLE, value);
2436
+ this.element.setAttribute('aria-disabled', '' + value);
2437
+ }
2438
+ /**
2439
+ * Get the properties to be maintained in the persisted state.
2440
+ *
2441
+ * @returns {string} - It returns the persisted state.
2442
+ */
2443
+ protected getPersistData(): string {
2444
+ return this.addOnPersist(['selectedItem', 'actEleId']);
2445
+ }
2446
+ /**
2447
+ * Returns the current module name.
2448
+ *
2449
+ * @returns {string} - It returns the current module name.
2450
+ * @private
2451
+ */
2452
+ protected getModuleName(): string {
2453
+ return 'tab';
2454
+ }
2455
+ /**
2456
+ * Gets called when the model property changes.The data that describes the old and new values of the property that changed.
2457
+ *
2458
+ * @param {TabModel} newProp - It contains the new value of data.
2459
+ * @param {TabModel} oldProp - It contains the old value of data.
2460
+ * @returns {void}
2461
+ * @private
2462
+ */
2463
+ public onPropertyChanged(newProp: TabModel, oldProp: TabModel): void {
2464
+ for (const prop of Object.keys(newProp)) {
2465
+ switch (prop) {
2466
+ case 'width':
2467
+ setStyle(this.element, { width: formatUnit(newProp.width) });
2468
+ break;
2469
+ case 'height':
2470
+ setStyle(this.element, { height: formatUnit(newProp.height) });
2471
+ this.setContentHeight(false);
2472
+ break;
2473
+ case 'cssClass':
2474
+ if (oldProp.cssClass !== '' && !isNullOrUndefined(oldProp.cssClass)) {
2475
+ this.setCssClass(this.element, oldProp.cssClass, false);
2476
+ this.setCssClass(this.element, newProp.cssClass, true);
2477
+ } else {
2478
+ this.setCssClass(this.element, newProp.cssClass, true);
2479
+ }
2480
+ break;
2481
+ case 'items':
2482
+ this.evalOnPropertyChangeItems(newProp, oldProp);
2483
+ break;
2484
+ case 'showCloseButton':
2485
+ this.setCloseButton(newProp.showCloseButton);
2486
+ break;
2487
+ case 'reorderActiveTab':
2488
+ this.refreshActiveTabBorder();
2489
+ break;
2490
+ case 'selectedItem':
2491
+ this.selectedItem = oldProp.selectedItem;
2492
+ this.select(newProp.selectedItem);
2493
+ break;
2494
+ case 'headerPlacement':
2495
+ this.changeOrientation(newProp.headerPlacement);
2496
+ break;
2497
+ case 'enableRtl':
2498
+ this.setRTL(newProp.enableRtl);
2499
+ break;
2500
+ case 'overflowMode':
2501
+ this.tbObj.overflowMode = newProp.overflowMode;
2502
+ this.tbObj.dataBind();
2503
+ this.refreshActiveTabBorder();
2504
+ break;
2505
+ case 'heightAdjustMode':
2506
+ this.setContentHeight(false);
2507
+ this.select(this.selectedItem);
2508
+ break;
2509
+ case 'scrollStep':
2510
+ if (this.tbObj) {
2511
+ this.tbObj.scrollStep = this.scrollStep;
2512
+ }
2513
+ break;
2514
+ case 'allowDragAndDrop':
2515
+ this.bindDraggable();
2516
+ break;
2517
+ case 'dragArea':
2518
+ if (this.allowDragAndDrop) {
2519
+ this.draggableItems.forEach((item: Draggable) => {
2520
+ item.dragArea = this.dragArea;
2521
+ });
2522
+ this.refresh();
2523
+ }
2524
+ break;
2525
+ }
2526
+ }
2527
+ }
2528
+
2529
+ public refreshActiveTab(): void {
2530
+ if ((this as any).isReact) {
2531
+ this.clearTemplate();
2532
+ }
2533
+ if (!this.isTemplate) {
2534
+ if (this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE)) {
2535
+ detach(this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE).children[0]);
2536
+ detach(this.element.querySelector('.' + CLS_CONTENT).querySelector('.' + CLS_ACTIVE).children[0]);
2537
+ const item: TabItemModel = this.items[this.selectedItem];
2538
+ const pos: Str = (isNOU(item.header) || isNOU(item.header.iconPosition)) ? '' : item.header.iconPosition;
2539
+ const css: Str = (isNOU(item.header) || isNOU(item.header.iconCss)) ? '' : item.header.iconCss;
2540
+ const text: Str | HTEle = item.headerTemplate || item.header.text;
2541
+ const txtWrap: HTEle = this.createElement('div', { className: CLS_TEXT, attrs: { 'role': 'presentation' } });
2542
+ if (!isNOU((<HTEle>text).tagName)) {
2543
+ txtWrap.appendChild(text as HTEle);
2544
+ } else {
2545
+ this.headerTextCompile(txtWrap, text as string, this.selectedItem);
2546
+ }
2547
+ let tEle: HTEle;
2548
+ const icon: HTEle = this.createElement('span', {
2549
+ className: CLS_ICONS + ' ' + CLS_TAB_ICON + ' ' + CLS_ICON + '-' + pos + ' ' + css
2550
+ });
2551
+ const tConts: HTEle = this.createElement('div', { className: CLS_TEXT_WRAP });
2552
+ tConts.appendChild(txtWrap);
2553
+ if ((text !== '' && text !== undefined) && css !== '') {
2554
+ if ((pos === 'left' || pos === 'top')) {
2555
+ tConts.insertBefore(icon, tConts.firstElementChild);
2556
+ } else {
2557
+ tConts.appendChild(icon);
2558
+ }
2559
+ tEle = txtWrap;
2560
+ this.isIconAlone = false;
2561
+ } else {
2562
+ tEle = ((css === '') ? txtWrap : icon);
2563
+ if (tEle === icon) {
2564
+ detach(txtWrap); tConts.appendChild(icon); this.isIconAlone = true;
2565
+ }
2566
+ }
2567
+ const wrapAtt: { [key: string]: string } = (item.disabled) ? {} : { tabIndex: '-1' };
2568
+ tConts.appendChild(this.btnCls.cloneNode(true));
2569
+ const wraper: HTEle = this.createElement('div', { className: CLS_WRAP, attrs: wrapAtt });
2570
+ wraper.appendChild(tConts);
2571
+ if (pos === 'top' || pos === 'bottom') {
2572
+ this.element.classList.add('e-vertical-icon');
2573
+ }
2574
+ this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE).appendChild(wraper);
2575
+ const crElem: HTEle = this.createElement('div');
2576
+ let cnt: string | HTMLElement = item.content; let eleStr: string;
2577
+ if (typeof cnt === 'string' || isNOU((<HTEle>cnt).innerHTML)) {
2578
+ if (typeof cnt === 'string' && this.enableHtmlSanitizer) {
2579
+ cnt = SanitizeHtmlHelper.sanitize(<Str>cnt);
2580
+ }
2581
+ if ((<Str>cnt)[0] === '.' || (<Str>cnt)[0] === '#') {
2582
+ if (document.querySelectorAll(<string>cnt).length) {
2583
+ const eleVal: HTEle = <HTEle>document.querySelector(<string>cnt);
2584
+ eleStr = eleVal.outerHTML.trim();
2585
+ crElem.appendChild(eleVal);
2586
+ eleVal.style.display = '';
2587
+ } else {
2588
+ this.compileElement(crElem, <Str>cnt, 'content', this.selectedItem);
2589
+ }
2590
+ } else {
2591
+ this.compileElement(crElem, <Str>cnt, 'content', this.selectedItem);
2592
+ }
2593
+ } else {
2594
+ crElem.appendChild(cnt);
2595
+ }
2596
+ if (!isNOU(eleStr)) {
2597
+ if (this.templateEle.indexOf(cnt.toString()) === -1) {
2598
+ this.templateEle.push(cnt.toString());
2599
+ }
2600
+ }
2601
+ this.element.querySelector('.' + CLS_ITEM + '.' + CLS_ACTIVE).appendChild(crElem);
2602
+ }
2603
+ } else {
2604
+ const tabItems: HTMLElement = this.element.querySelector('.' + CLS_TB_ITEMS);
2605
+ const element: HTMLElement = this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE);
2606
+ const id: string | number = element.id;
2607
+ const num: number = (id.indexOf('_'));
2608
+ const index: number = parseInt(id.substring(num + 1), 10);
2609
+ const header: string = element.innerText;
2610
+ const detachContent: Element = this.element.querySelector('.' + CLS_CONTENT).querySelector('.' + CLS_ACTIVE).children[0];
2611
+ const mainContents: string = detachContent.innerHTML;
2612
+ detach(element);
2613
+ detach(detachContent);
2614
+ const attr: object = {
2615
+ className: CLS_TB_ITEM + ' ' + CLS_TEMPLATE + ' ' + CLS_ACTIVE, id: CLS_ITEM + this.tabId + '_' + index,
2616
+ attrs: {
2617
+ role: 'tab', 'aria-controls': CLS_CONTENT + this.tabId + '_' + index,
2618
+ 'aria-disabled': 'false', 'aria-selected': 'true'
2619
+ }
2620
+ };
2621
+ const txtString: Str = this.createElement('span', {
2622
+ className: CLS_TEXT, innerHTML: header, attrs: { 'role': 'presentation' }
2623
+ }).outerHTML;
2624
+ const conte: Str = this.createElement('div', {
2625
+ className: CLS_TEXT_WRAP, innerHTML: txtString + this.btnCls.outerHTML
2626
+ }).outerHTML;
2627
+ const wrap: HTEle = this.createElement('div', { className: CLS_WRAP, innerHTML: conte, attrs: { tabIndex: '-1' } });
2628
+ tabItems.insertBefore(this.createElement('div', attr), tabItems.children[index + 1]);
2629
+ this.element.querySelector('.' + CLS_TB_ITEM + '.' + CLS_ACTIVE).appendChild(wrap);
2630
+ const crElem: HTEle = this.createElement('div', { innerHTML: mainContents });
2631
+ this.element.querySelector('.' + CLS_CONTENT).querySelector('.' + CLS_ACTIVE).appendChild(crElem);
2632
+ }
2633
+ if ((this as any).isReact) {
2634
+ this.renderReactTemplates();
2635
+ }
2636
+ }
2637
+ }