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