ngx-bootstrap-tabs.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. import { Directive, ViewContainerRef, Input, Injectable, Component, Renderer2, ElementRef, HostBinding, Output, EventEmitter, TemplateRef, NgModule } from '@angular/core';
  2. import { CommonModule } from '@angular/common';
  3. /**
  4. * @fileoverview added by tsickle
  5. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  6. */
  7. var NgTranscludeDirective = /** @class */ (function () {
  8. function NgTranscludeDirective(viewRef) {
  9. this.viewRef = viewRef;
  10. }
  11. Object.defineProperty(NgTranscludeDirective.prototype, "ngTransclude", {
  12. /* tslint:disable-next-line:no-any */
  13. get: /* tslint:disable-next-line:no-any */
  14. /**
  15. * @return {?}
  16. */
  17. function () {
  18. return this._ngTransclude;
  19. },
  20. set: /**
  21. * @param {?} templateRef
  22. * @return {?}
  23. */
  24. function (templateRef) {
  25. this._ngTransclude = templateRef;
  26. if (templateRef) {
  27. this.viewRef.createEmbeddedView(templateRef);
  28. }
  29. },
  30. enumerable: true,
  31. configurable: true
  32. });
  33. NgTranscludeDirective.decorators = [
  34. { type: Directive, args: [{
  35. selector: '[ngTransclude]'
  36. },] }
  37. ];
  38. /** @nocollapse */
  39. NgTranscludeDirective.ctorParameters = function () { return [
  40. { type: ViewContainerRef }
  41. ]; };
  42. NgTranscludeDirective.propDecorators = {
  43. ngTransclude: [{ type: Input }]
  44. };
  45. return NgTranscludeDirective;
  46. }());
  47. /**
  48. * @fileoverview added by tsickle
  49. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  50. */
  51. var TabsetConfig = /** @class */ (function () {
  52. function TabsetConfig() {
  53. /**
  54. * provides default navigation context class: 'tabs' or 'pills'
  55. */
  56. this.type = 'tabs';
  57. }
  58. TabsetConfig.decorators = [
  59. { type: Injectable }
  60. ];
  61. return TabsetConfig;
  62. }());
  63. /**
  64. * @fileoverview added by tsickle
  65. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  66. */
  67. // todo: add active event to tab
  68. // todo: fix? mixing static and dynamic tabs position tabs in order of creation
  69. var TabsetComponent = /** @class */ (function () {
  70. function TabsetComponent(config, renderer, elementRef) {
  71. this.renderer = renderer;
  72. this.elementRef = elementRef;
  73. this.clazz = true;
  74. this.tabs = [];
  75. this.classMap = {};
  76. Object.assign(this, config);
  77. }
  78. Object.defineProperty(TabsetComponent.prototype, "vertical", {
  79. /** if true tabs will be placed vertically */
  80. get: /**
  81. * if true tabs will be placed vertically
  82. * @return {?}
  83. */
  84. function () {
  85. return this._vertical;
  86. },
  87. set: /**
  88. * @param {?} value
  89. * @return {?}
  90. */
  91. function (value) {
  92. this._vertical = value;
  93. this.setClassMap();
  94. },
  95. enumerable: true,
  96. configurable: true
  97. });
  98. Object.defineProperty(TabsetComponent.prototype, "justified", {
  99. /** if true tabs fill the container and have a consistent width */
  100. get: /**
  101. * if true tabs fill the container and have a consistent width
  102. * @return {?}
  103. */
  104. function () {
  105. return this._justified;
  106. },
  107. set: /**
  108. * @param {?} value
  109. * @return {?}
  110. */
  111. function (value) {
  112. this._justified = value;
  113. this.setClassMap();
  114. },
  115. enumerable: true,
  116. configurable: true
  117. });
  118. Object.defineProperty(TabsetComponent.prototype, "type", {
  119. /** navigation context class: 'tabs' or 'pills' */
  120. get: /**
  121. * navigation context class: 'tabs' or 'pills'
  122. * @return {?}
  123. */
  124. function () {
  125. return this._type;
  126. },
  127. set: /**
  128. * @param {?} value
  129. * @return {?}
  130. */
  131. function (value) {
  132. this._type = value;
  133. this.setClassMap();
  134. },
  135. enumerable: true,
  136. configurable: true
  137. });
  138. /**
  139. * @return {?}
  140. */
  141. TabsetComponent.prototype.ngOnDestroy = /**
  142. * @return {?}
  143. */
  144. function () {
  145. this.isDestroyed = true;
  146. };
  147. /**
  148. * @param {?} tab
  149. * @return {?}
  150. */
  151. TabsetComponent.prototype.addTab = /**
  152. * @param {?} tab
  153. * @return {?}
  154. */
  155. function (tab) {
  156. this.tabs.push(tab);
  157. tab.active = this.tabs.length === 1 && typeof tab.active === 'undefined';
  158. };
  159. /**
  160. * @param {?} tab
  161. * @param {?=} options
  162. * @return {?}
  163. */
  164. TabsetComponent.prototype.removeTab = /**
  165. * @param {?} tab
  166. * @param {?=} options
  167. * @return {?}
  168. */
  169. function (tab, options) {
  170. if (options === void 0) { options = { reselect: true, emit: true }; }
  171. /** @type {?} */
  172. var index = this.tabs.indexOf(tab);
  173. if (index === -1 || this.isDestroyed) {
  174. return;
  175. }
  176. // Select a new tab if the tab to be removed is selected and not destroyed
  177. if (options.reselect && tab.active && this.hasAvailableTabs(index)) {
  178. /** @type {?} */
  179. var newActiveIndex = this.getClosestTabIndex(index);
  180. this.tabs[newActiveIndex].active = true;
  181. }
  182. if (options.emit) {
  183. tab.removed.emit(tab);
  184. }
  185. this.tabs.splice(index, 1);
  186. if (tab.elementRef.nativeElement.parentNode) {
  187. this.renderer.removeChild(tab.elementRef.nativeElement.parentNode, tab.elementRef.nativeElement);
  188. }
  189. };
  190. /* tslint:disable-next-line: cyclomatic-complexity */
  191. /* tslint:disable-next-line: cyclomatic-complexity */
  192. /**
  193. * @param {?} event
  194. * @param {?} index
  195. * @return {?}
  196. */
  197. TabsetComponent.prototype.keyNavActions = /* tslint:disable-next-line: cyclomatic-complexity */
  198. /**
  199. * @param {?} event
  200. * @param {?} index
  201. * @return {?}
  202. */
  203. function (event, index) {
  204. /** @type {?} */
  205. var list = Array.from(this.elementRef.nativeElement.querySelectorAll('.nav-link'));
  206. // const activeElList = list.filter((el: HTMLElement) => !el.classList.contains('disabled'));
  207. // tslint:disable-next-line:deprecation
  208. if (event.keyCode === 13 || event.key === 'Enter' || event.keyCode === 32 || event.key === 'Space') {
  209. event.preventDefault();
  210. /** @type {?} */
  211. var currentTab = list[(index) % list.length];
  212. currentTab.click();
  213. return;
  214. }
  215. // tslint:disable-next-line:deprecation
  216. if (event.keyCode === 39 || event.key === 'RightArrow') {
  217. /** @type {?} */
  218. var nextTab = void 0;
  219. /** @type {?} */
  220. var shift = 1;
  221. do {
  222. nextTab = list[(index + shift) % list.length];
  223. shift++;
  224. } while (nextTab.classList.contains('disabled'));
  225. nextTab.focus();
  226. return;
  227. }
  228. // tslint:disable-next-line:deprecation
  229. if (event.keyCode === 37 || event.key === 'LeftArrow') {
  230. /** @type {?} */
  231. var previousTab = void 0;
  232. /** @type {?} */
  233. var shift = 1;
  234. /** @type {?} */
  235. var i = index;
  236. do {
  237. if ((i - shift) < 0) {
  238. i = list.length - 1;
  239. previousTab = list[i];
  240. shift = 0;
  241. }
  242. else {
  243. previousTab = list[i - shift];
  244. }
  245. shift++;
  246. } while (previousTab.classList.contains('disabled'));
  247. previousTab.focus();
  248. return;
  249. }
  250. // tslint:disable-next-line:deprecation
  251. if (event.keyCode === 36 || event.key === 'Home') {
  252. event.preventDefault();
  253. /** @type {?} */
  254. var firstTab = void 0;
  255. /** @type {?} */
  256. var shift = 0;
  257. do {
  258. firstTab = list[shift % list.length];
  259. shift++;
  260. } while (firstTab.classList.contains('disabled'));
  261. firstTab.focus();
  262. return;
  263. }
  264. // tslint:disable-next-line:deprecation
  265. if (event.keyCode === 35 || event.key === 'End') {
  266. event.preventDefault();
  267. /** @type {?} */
  268. var lastTab = void 0;
  269. /** @type {?} */
  270. var shift = 1;
  271. /** @type {?} */
  272. var i = index;
  273. do {
  274. if ((i - shift) < 0) {
  275. i = list.length - 1;
  276. lastTab = list[i];
  277. shift = 0;
  278. }
  279. else {
  280. lastTab = list[i - shift];
  281. }
  282. shift++;
  283. } while (lastTab.classList.contains('disabled'));
  284. lastTab.focus();
  285. return;
  286. }
  287. // tslint:disable-next-line:deprecation
  288. if (event.keyCode === 46 || event.key === 'Delete') {
  289. if (this.tabs[index].removable) {
  290. this.removeTab(this.tabs[index]);
  291. if (list[index + 1]) {
  292. list[(index + 1) % list.length].focus();
  293. return;
  294. }
  295. if (list[list.length - 1]) {
  296. list[0].focus();
  297. }
  298. }
  299. }
  300. };
  301. /**
  302. * @protected
  303. * @param {?} index
  304. * @return {?}
  305. */
  306. TabsetComponent.prototype.getClosestTabIndex = /**
  307. * @protected
  308. * @param {?} index
  309. * @return {?}
  310. */
  311. function (index) {
  312. /** @type {?} */
  313. var tabsLength = this.tabs.length;
  314. if (!tabsLength) {
  315. return -1;
  316. }
  317. for (var step = 1; step <= tabsLength; step += 1) {
  318. /** @type {?} */
  319. var prevIndex = index - step;
  320. /** @type {?} */
  321. var nextIndex = index + step;
  322. if (this.tabs[prevIndex] && !this.tabs[prevIndex].disabled) {
  323. return prevIndex;
  324. }
  325. if (this.tabs[nextIndex] && !this.tabs[nextIndex].disabled) {
  326. return nextIndex;
  327. }
  328. }
  329. return -1;
  330. };
  331. /**
  332. * @protected
  333. * @param {?} index
  334. * @return {?}
  335. */
  336. TabsetComponent.prototype.hasAvailableTabs = /**
  337. * @protected
  338. * @param {?} index
  339. * @return {?}
  340. */
  341. function (index) {
  342. /** @type {?} */
  343. var tabsLength = this.tabs.length;
  344. if (!tabsLength) {
  345. return false;
  346. }
  347. for (var i = 0; i < tabsLength; i += 1) {
  348. if (!this.tabs[i].disabled && i !== index) {
  349. return true;
  350. }
  351. }
  352. return false;
  353. };
  354. /**
  355. * @protected
  356. * @return {?}
  357. */
  358. TabsetComponent.prototype.setClassMap = /**
  359. * @protected
  360. * @return {?}
  361. */
  362. function () {
  363. var _a;
  364. this.classMap = (_a = {
  365. 'nav-stacked': this.vertical,
  366. 'flex-column': this.vertical,
  367. 'nav-justified': this.justified
  368. },
  369. _a["nav-" + this.type] = true,
  370. _a);
  371. };
  372. TabsetComponent.decorators = [
  373. { type: Component, args: [{
  374. selector: 'tabset',
  375. template: "<ul class=\"nav\" [ngClass]=\"classMap\" (click)=\"$event.preventDefault()\">\n <li *ngFor=\"let tabz of tabs; let i = index\" [ngClass]=\"['nav-item', tabz.customClass || '']\"\n [class.active]=\"tabz.active\" [class.disabled]=\"tabz.disabled\" (keydown)=\"keyNavActions($event, i)\">\n <a href=\"javascript:void(0);\" class=\"nav-link\"\n [attr.id]=\"tabz.id ? tabz.id + '-link' : ''\"\n [class.active]=\"tabz.active\" [class.disabled]=\"tabz.disabled\"\n (click)=\"tabz.active = true\">\n <span [ngTransclude]=\"tabz.headingRef\">{{ tabz.heading }}</span>\n <span *ngIf=\"tabz.removable\" (click)=\"$event.preventDefault(); removeTab(tabz);\" class=\"bs-remove-tab\"> &#10060;</span>\n </a>\n </li>\n</ul>\n<div class=\"tab-content\">\n <ng-content></ng-content>\n</div>\n",
  376. styles: [":host .nav-tabs .nav-item.disabled a.disabled{cursor:default}"]
  377. }] }
  378. ];
  379. /** @nocollapse */
  380. TabsetComponent.ctorParameters = function () { return [
  381. { type: TabsetConfig },
  382. { type: Renderer2 },
  383. { type: ElementRef }
  384. ]; };
  385. TabsetComponent.propDecorators = {
  386. vertical: [{ type: Input }],
  387. justified: [{ type: Input }],
  388. type: [{ type: Input }],
  389. clazz: [{ type: HostBinding, args: ['class.tab-container',] }]
  390. };
  391. return TabsetComponent;
  392. }());
  393. /**
  394. * @fileoverview added by tsickle
  395. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  396. */
  397. var TabDirective = /** @class */ (function () {
  398. function TabDirective(tabset, elementRef, renderer) {
  399. this.elementRef = elementRef;
  400. this.renderer = renderer;
  401. /**
  402. * fired when tab became active, $event:Tab equals to selected instance of Tab component
  403. */
  404. this.selectTab = new EventEmitter();
  405. /**
  406. * fired when tab became inactive, $event:Tab equals to deselected instance of Tab component
  407. */
  408. this.deselect = new EventEmitter();
  409. /**
  410. * fired before tab will be removed, $event:Tab equals to instance of removed tab
  411. */
  412. this.removed = new EventEmitter();
  413. this.addClass = true;
  414. this.tabset = tabset;
  415. this.tabset.addTab(this);
  416. }
  417. Object.defineProperty(TabDirective.prototype, "customClass", {
  418. /** if set, will be added to the tab's class attribute. Multiple classes are supported. */
  419. get: /**
  420. * if set, will be added to the tab's class attribute. Multiple classes are supported.
  421. * @return {?}
  422. */
  423. function () {
  424. return this._customClass;
  425. },
  426. set: /**
  427. * @param {?} customClass
  428. * @return {?}
  429. */
  430. function (customClass) {
  431. var _this = this;
  432. if (this.customClass) {
  433. this.customClass.split(' ').forEach((/**
  434. * @param {?} cssClass
  435. * @return {?}
  436. */
  437. function (cssClass) {
  438. _this.renderer.removeClass(_this.elementRef.nativeElement, cssClass);
  439. }));
  440. }
  441. this._customClass = customClass ? customClass.trim() : null;
  442. if (this.customClass) {
  443. this.customClass.split(' ').forEach((/**
  444. * @param {?} cssClass
  445. * @return {?}
  446. */
  447. function (cssClass) {
  448. _this.renderer.addClass(_this.elementRef.nativeElement, cssClass);
  449. }));
  450. }
  451. },
  452. enumerable: true,
  453. configurable: true
  454. });
  455. Object.defineProperty(TabDirective.prototype, "active", {
  456. /** tab active state toggle */
  457. get: /**
  458. * tab active state toggle
  459. * @return {?}
  460. */
  461. function () {
  462. return this._active;
  463. },
  464. set: /**
  465. * @param {?} active
  466. * @return {?}
  467. */
  468. function (active) {
  469. var _this = this;
  470. if (this._active === active) {
  471. return;
  472. }
  473. if ((this.disabled && active) || !active) {
  474. if (this._active && !active) {
  475. this.deselect.emit(this);
  476. this._active = active;
  477. }
  478. return;
  479. }
  480. this._active = active;
  481. this.selectTab.emit(this);
  482. this.tabset.tabs.forEach((/**
  483. * @param {?} tab
  484. * @return {?}
  485. */
  486. function (tab) {
  487. if (tab !== _this) {
  488. tab.active = false;
  489. }
  490. }));
  491. },
  492. enumerable: true,
  493. configurable: true
  494. });
  495. /**
  496. * @return {?}
  497. */
  498. TabDirective.prototype.ngOnInit = /**
  499. * @return {?}
  500. */
  501. function () {
  502. this.removable = this.removable;
  503. };
  504. /**
  505. * @return {?}
  506. */
  507. TabDirective.prototype.ngOnDestroy = /**
  508. * @return {?}
  509. */
  510. function () {
  511. this.tabset.removeTab(this, { reselect: false, emit: false });
  512. };
  513. TabDirective.decorators = [
  514. { type: Directive, args: [{ selector: 'tab, [tab]' },] }
  515. ];
  516. /** @nocollapse */
  517. TabDirective.ctorParameters = function () { return [
  518. { type: TabsetComponent },
  519. { type: ElementRef },
  520. { type: Renderer2 }
  521. ]; };
  522. TabDirective.propDecorators = {
  523. heading: [{ type: Input }],
  524. id: [{ type: HostBinding, args: ['attr.id',] }, { type: Input }],
  525. disabled: [{ type: Input }],
  526. removable: [{ type: Input }],
  527. customClass: [{ type: Input }],
  528. active: [{ type: HostBinding, args: ['class.active',] }, { type: Input }],
  529. selectTab: [{ type: Output }],
  530. deselect: [{ type: Output }],
  531. removed: [{ type: Output }],
  532. addClass: [{ type: HostBinding, args: ['class.tab-pane',] }]
  533. };
  534. return TabDirective;
  535. }());
  536. /**
  537. * @fileoverview added by tsickle
  538. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  539. */
  540. /**
  541. * Should be used to mark <ng-template> element as a template for tab heading
  542. */
  543. var TabHeadingDirective = /** @class */ (function () {
  544. /* tslint:disable-next-line:no-any */
  545. function TabHeadingDirective(templateRef, tab) {
  546. tab.headingRef = templateRef;
  547. }
  548. TabHeadingDirective.decorators = [
  549. { type: Directive, args: [{ selector: '[tabHeading]' },] }
  550. ];
  551. /** @nocollapse */
  552. TabHeadingDirective.ctorParameters = function () { return [
  553. { type: TemplateRef },
  554. { type: TabDirective }
  555. ]; };
  556. return TabHeadingDirective;
  557. }());
  558. /**
  559. * @fileoverview added by tsickle
  560. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  561. */
  562. var TabsModule = /** @class */ (function () {
  563. function TabsModule() {
  564. }
  565. /**
  566. * @return {?}
  567. */
  568. TabsModule.forRoot = /**
  569. * @return {?}
  570. */
  571. function () {
  572. return {
  573. ngModule: TabsModule,
  574. providers: [TabsetConfig]
  575. };
  576. };
  577. TabsModule.decorators = [
  578. { type: NgModule, args: [{
  579. imports: [CommonModule],
  580. declarations: [
  581. NgTranscludeDirective,
  582. TabDirective,
  583. TabsetComponent,
  584. TabHeadingDirective
  585. ],
  586. exports: [
  587. TabDirective,
  588. TabsetComponent,
  589. TabHeadingDirective,
  590. NgTranscludeDirective
  591. ]
  592. },] }
  593. ];
  594. return TabsModule;
  595. }());
  596. export { NgTranscludeDirective, TabDirective, TabHeadingDirective, TabsModule, TabsetComponent, TabsetConfig };
  597. //# sourceMappingURL=ngx-bootstrap-tabs.js.map