@syncfusion/ej2-navigations 31.1.17 → 31.1.20

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