@angular/material 8.1.4 → 8.2.3
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/_theming.scss +13 -11
- package/autocomplete/typings/autocomplete-trigger.d.ts +5 -2
- package/autocomplete/typings/index.metadata.json +1 -1
- package/bundles/material-autocomplete.umd.js +48 -20
- package/bundles/material-autocomplete.umd.js.map +1 -1
- package/bundles/material-autocomplete.umd.min.js +1 -1
- package/bundles/material-autocomplete.umd.min.js.map +1 -1
- package/bundles/material-button.umd.js +5 -6
- package/bundles/material-button.umd.js.map +1 -1
- package/bundles/material-button.umd.min.js +1 -1
- package/bundles/material-button.umd.min.js.map +1 -1
- package/bundles/material-card.umd.js +1 -1
- package/bundles/material-card.umd.js.map +1 -1
- package/bundles/material-card.umd.min.js +1 -1
- package/bundles/material-card.umd.min.js.map +1 -1
- package/bundles/material-checkbox.umd.js +1 -1
- package/bundles/material-checkbox.umd.js.map +1 -1
- package/bundles/material-checkbox.umd.min.js.map +1 -1
- package/bundles/material-chips.umd.js +24 -4
- package/bundles/material-chips.umd.js.map +1 -1
- package/bundles/material-chips.umd.min.js +1 -1
- package/bundles/material-chips.umd.min.js.map +1 -1
- package/bundles/material-core.umd.js +20 -18
- package/bundles/material-core.umd.js.map +1 -1
- package/bundles/material-core.umd.min.js +2 -2
- package/bundles/material-core.umd.min.js.map +1 -1
- package/bundles/material-datepicker.umd.js +22 -2
- package/bundles/material-datepicker.umd.js.map +1 -1
- package/bundles/material-datepicker.umd.min.js +2 -2
- package/bundles/material-datepicker.umd.min.js.map +1 -1
- package/bundles/material-dialog.umd.js +28 -5
- package/bundles/material-dialog.umd.js.map +1 -1
- package/bundles/material-dialog.umd.min.js +1 -1
- package/bundles/material-dialog.umd.min.js.map +1 -1
- package/bundles/material-form-field.umd.js +15 -2
- package/bundles/material-form-field.umd.js.map +1 -1
- package/bundles/material-form-field.umd.min.js +1 -1
- package/bundles/material-form-field.umd.min.js.map +1 -1
- package/bundles/material-grid-list.umd.js +1 -1
- package/bundles/material-grid-list.umd.min.js +1 -1
- package/bundles/material-icon.umd.js +103 -42
- package/bundles/material-icon.umd.js.map +1 -1
- package/bundles/material-icon.umd.min.js +1 -1
- package/bundles/material-icon.umd.min.js.map +1 -1
- package/bundles/material-list.umd.js +4 -1
- package/bundles/material-list.umd.js.map +1 -1
- package/bundles/material-list.umd.min.js +1 -1
- package/bundles/material-list.umd.min.js.map +1 -1
- package/bundles/material-menu.umd.js +35 -19
- package/bundles/material-menu.umd.js.map +1 -1
- package/bundles/material-menu.umd.min.js +1 -1
- package/bundles/material-menu.umd.min.js.map +1 -1
- package/bundles/material-paginator.umd.js +1 -1
- package/bundles/material-paginator.umd.js.map +1 -1
- package/bundles/material-paginator.umd.min.js +1 -1
- package/bundles/material-paginator.umd.min.js.map +1 -1
- package/bundles/material-progress-spinner.umd.js +34 -23
- package/bundles/material-progress-spinner.umd.js.map +1 -1
- package/bundles/material-progress-spinner.umd.min.js +1 -1
- package/bundles/material-progress-spinner.umd.min.js.map +1 -1
- package/bundles/material-radio.umd.js +3 -0
- package/bundles/material-radio.umd.js.map +1 -1
- package/bundles/material-radio.umd.min.js +1 -1
- package/bundles/material-radio.umd.min.js.map +1 -1
- package/bundles/material-select.umd.js +14 -2
- package/bundles/material-select.umd.js.map +1 -1
- package/bundles/material-select.umd.min.js +1 -1
- package/bundles/material-select.umd.min.js.map +1 -1
- package/bundles/material-slide-toggle.umd.js +3 -1
- package/bundles/material-slide-toggle.umd.js.map +1 -1
- package/bundles/material-slide-toggle.umd.min.js +1 -1
- package/bundles/material-slide-toggle.umd.min.js.map +1 -1
- package/bundles/material-slider.umd.js +6 -3
- package/bundles/material-slider.umd.js.map +1 -1
- package/bundles/material-slider.umd.min.js +1 -1
- package/bundles/material-slider.umd.min.js.map +1 -1
- package/bundles/material-snack-bar.umd.js +7 -8
- package/bundles/material-snack-bar.umd.js.map +1 -1
- package/bundles/material-snack-bar.umd.min.js +1 -1
- package/bundles/material-snack-bar.umd.min.js.map +1 -1
- package/bundles/material-sort.umd.js +0 -1
- package/bundles/material-sort.umd.js.map +1 -1
- package/bundles/material-sort.umd.min.js +1 -1
- package/bundles/material-sort.umd.min.js.map +1 -1
- package/bundles/material-table.umd.js +14 -4
- package/bundles/material-table.umd.js.map +1 -1
- package/bundles/material-table.umd.min.js +1 -1
- package/bundles/material-table.umd.min.js.map +1 -1
- package/bundles/material-tabs.umd.js +1390 -1208
- package/bundles/material-tabs.umd.js.map +1 -1
- package/bundles/material-tabs.umd.min.js +2 -2
- package/bundles/material-tabs.umd.min.js.map +1 -1
- package/bundles/material-tooltip.umd.js +16 -1
- package/bundles/material-tooltip.umd.js.map +1 -1
- package/bundles/material-tooltip.umd.min.js +1 -1
- package/bundles/material-tooltip.umd.min.js.map +1 -1
- package/bundles/material.umd.js +1767 -1346
- package/bundles/material.umd.js.map +1 -1
- package/bundles/material.umd.min.js +19 -19
- package/bundles/material.umd.min.js.map +1 -1
- package/button/typings/button.d.ts +1 -1
- package/button/typings/index.metadata.json +1 -1
- package/card/typings/index.metadata.json +1 -1
- package/chips/typings/chip.d.ts +4 -2
- package/chips/typings/index.metadata.json +1 -1
- package/core/typings/common-behaviors/common-module.d.ts +2 -2
- package/core/typings/datetime/date-adapter.d.ts +1 -1
- package/core/typings/datetime/native-date-adapter.d.ts +1 -1
- package/core/typings/index.metadata.json +1 -1
- package/core/typings/ripple/ripple-renderer.d.ts +2 -2
- package/core/typings/ripple/ripple.d.ts +1 -1
- package/datepicker/typings/datepicker-intl.d.ts +2 -0
- package/datepicker/typings/index.metadata.json +1 -1
- package/dialog/typings/dialog-config.d.ts +9 -7
- package/dialog/typings/dialog-content-directives.d.ts +2 -0
- package/dialog/typings/dialog-ref.d.ts +10 -0
- package/dialog/typings/index.metadata.json +1 -1
- package/esm2015/autocomplete.js +44 -19
- package/esm2015/autocomplete.js.map +1 -1
- package/esm2015/button.js +3 -5
- package/esm2015/button.js.map +1 -1
- package/esm2015/card.js +1 -1
- package/esm2015/card.js.map +1 -1
- package/esm2015/checkbox.js +1 -1
- package/esm2015/checkbox.js.map +1 -1
- package/esm2015/chips.js +22 -5
- package/esm2015/chips.js.map +1 -1
- package/esm2015/core.js +19 -17
- package/esm2015/core.js.map +1 -1
- package/esm2015/datepicker.js +15 -2
- package/esm2015/datepicker.js.map +1 -1
- package/esm2015/dialog.js +23 -5
- package/esm2015/dialog.js.map +1 -1
- package/esm2015/form-field.js +15 -2
- package/esm2015/form-field.js.map +1 -1
- package/esm2015/grid-list.js +1 -1
- package/esm2015/icon.js +93 -40
- package/esm2015/icon.js.map +1 -1
- package/esm2015/list.js +4 -1
- package/esm2015/list.js.map +1 -1
- package/esm2015/material.js +3 -3
- package/esm2015/menu.js +31 -10
- package/esm2015/menu.js.map +1 -1
- package/esm2015/paginator.js +1 -1
- package/esm2015/paginator.js.map +1 -1
- package/esm2015/progress-spinner.js +31 -23
- package/esm2015/progress-spinner.js.map +1 -1
- package/esm2015/radio.js +3 -0
- package/esm2015/radio.js.map +1 -1
- package/esm2015/select.js +14 -2
- package/esm2015/select.js.map +1 -1
- package/esm2015/slide-toggle.js +3 -1
- package/esm2015/slide-toggle.js.map +1 -1
- package/esm2015/slider.js +6 -2
- package/esm2015/slider.js.map +1 -1
- package/esm2015/snack-bar.js +7 -8
- package/esm2015/snack-bar.js.map +1 -1
- package/esm2015/sort.js +0 -1
- package/esm2015/sort.js.map +1 -1
- package/esm2015/table.js +9 -4
- package/esm2015/table.js.map +1 -1
- package/esm2015/tabs.js +1094 -890
- package/esm2015/tabs.js.map +1 -1
- package/esm2015/tooltip.js +15 -1
- package/esm2015/tooltip.js.map +1 -1
- package/esm5/autocomplete.es5.js +48 -19
- package/esm5/autocomplete.es5.js.map +1 -1
- package/esm5/button.es5.js +5 -6
- package/esm5/button.es5.js.map +1 -1
- package/esm5/card.es5.js +1 -1
- package/esm5/card.es5.js.map +1 -1
- package/esm5/checkbox.es5.js +1 -1
- package/esm5/checkbox.es5.js.map +1 -1
- package/esm5/chips.es5.js +25 -5
- package/esm5/chips.es5.js.map +1 -1
- package/esm5/core.es5.js +21 -19
- package/esm5/core.es5.js.map +1 -1
- package/esm5/datepicker.es5.js +22 -2
- package/esm5/datepicker.es5.js.map +1 -1
- package/esm5/dialog.es5.js +28 -5
- package/esm5/dialog.es5.js.map +1 -1
- package/esm5/form-field.es5.js +15 -2
- package/esm5/form-field.es5.js.map +1 -1
- package/esm5/grid-list.es5.js +1 -1
- package/esm5/icon.es5.js +101 -40
- package/esm5/icon.es5.js.map +1 -1
- package/esm5/list.es5.js +4 -1
- package/esm5/list.es5.js.map +1 -1
- package/esm5/material.es5.js +3 -3
- package/esm5/menu.es5.js +33 -17
- package/esm5/menu.es5.js.map +1 -1
- package/esm5/paginator.es5.js +1 -1
- package/esm5/paginator.es5.js.map +1 -1
- package/esm5/progress-spinner.es5.js +34 -23
- package/esm5/progress-spinner.es5.js.map +1 -1
- package/esm5/radio.es5.js +3 -0
- package/esm5/radio.es5.js.map +1 -1
- package/esm5/select.es5.js +14 -2
- package/esm5/select.es5.js.map +1 -1
- package/esm5/slide-toggle.es5.js +3 -1
- package/esm5/slide-toggle.es5.js.map +1 -1
- package/esm5/slider.es5.js +6 -3
- package/esm5/slider.es5.js.map +1 -1
- package/esm5/snack-bar.es5.js +7 -8
- package/esm5/snack-bar.es5.js.map +1 -1
- package/esm5/sort.es5.js +0 -1
- package/esm5/sort.es5.js.map +1 -1
- package/esm5/table.es5.js +14 -4
- package/esm5/table.es5.js.map +1 -1
- package/esm5/tabs.es5.js +1384 -1207
- package/esm5/tabs.es5.js.map +1 -1
- package/esm5/tooltip.es5.js +16 -1
- package/esm5/tooltip.es5.js.map +1 -1
- package/form-field/typings/form-field.d.ts +2 -0
- package/form-field/typings/index.metadata.json +1 -1
- package/grid-list/typings/index.d.ts +1 -1
- package/grid-list/typings/index.metadata.json +1 -1
- package/icon/typings/icon-registry.d.ts +17 -11
- package/icon/typings/icon.d.ts +3 -2
- package/icon/typings/index.metadata.json +1 -1
- package/list/typings/index.metadata.json +1 -1
- package/menu/typings/index.d.ts +2 -2
- package/menu/typings/index.metadata.json +1 -1
- package/menu/typings/menu-trigger.d.ts +2 -5
- package/package.json +5 -5
- package/prebuilt-themes/deeppurple-amber.css +1 -1
- package/prebuilt-themes/indigo-pink.css +1 -1
- package/prebuilt-themes/pink-bluegrey.css +1 -1
- package/prebuilt-themes/purple-green.css +1 -1
- package/progress-spinner/typings/index.metadata.json +1 -1
- package/progress-spinner/typings/progress-spinner.d.ts +3 -2
- package/radio/typings/index.metadata.json +1 -1
- package/schematics/ng-add/setup-project.js +8 -8
- package/schematics/ng-add/setup-project.js.map +1 -1
- package/schematics/ng-add/theming/theming.js +6 -6
- package/schematics/ng-add/theming/theming.js.map +1 -1
- package/schematics/ng-update/index.js +2 -2
- package/schematics/ng-update/index.js.map +1 -1
- package/select/typings/index.metadata.json +1 -1
- package/select/typings/select.d.ts +2 -0
- package/slide-toggle/typings/index.metadata.json +1 -1
- package/slider/typings/index.metadata.json +1 -1
- package/slider/typings/slider.d.ts +2 -2
- package/snack-bar/typings/index.metadata.json +1 -1
- package/sort/typings/index.metadata.json +1 -1
- package/table/typings/index.metadata.json +1 -1
- package/table/typings/table-data-source.d.ts +5 -0
- package/tabs/typings/index.d.ts +2 -2
- package/tabs/typings/index.metadata.json +1 -1
- package/tabs/typings/paginated-tab-header.d.ts +8 -5
- package/tabs/typings/public-api.d.ts +4 -4
- package/tabs/typings/tab-body.d.ts +11 -3
- package/tabs/typings/tab-group.d.ts +24 -11
- package/tabs/typings/tab-header.d.ts +12 -5
- package/tabs/typings/tab-nav-bar/tab-nav-bar.d.ts +38 -19
- package/tooltip/typings/index.metadata.json +1 -1
- package/typings/autocomplete/autocomplete-trigger.d.ts +5 -2
- package/typings/autocomplete/index.metadata.json +1 -1
- package/typings/button/button.d.ts +1 -1
- package/typings/button/index.metadata.json +1 -1
- package/typings/card/index.metadata.json +1 -1
- package/typings/chips/chip.d.ts +4 -2
- package/typings/chips/index.metadata.json +1 -1
- package/typings/core/common-behaviors/common-module.d.ts +2 -2
- package/typings/core/datetime/date-adapter.d.ts +1 -1
- package/typings/core/datetime/native-date-adapter.d.ts +1 -1
- package/typings/core/index.metadata.json +1 -1
- package/typings/core/ripple/ripple-renderer.d.ts +2 -2
- package/typings/core/ripple/ripple.d.ts +1 -1
- package/typings/datepicker/datepicker-intl.d.ts +2 -0
- package/typings/datepicker/index.metadata.json +1 -1
- package/typings/dialog/dialog-config.d.ts +9 -7
- package/typings/dialog/dialog-content-directives.d.ts +2 -0
- package/typings/dialog/dialog-ref.d.ts +10 -0
- package/typings/dialog/index.metadata.json +1 -1
- package/typings/esm5/autocomplete/autocomplete-trigger.d.ts +5 -2
- package/typings/esm5/autocomplete/index.metadata.json +1 -1
- package/typings/esm5/button/button.d.ts +1 -1
- package/typings/esm5/button/index.metadata.json +1 -1
- package/typings/esm5/card/index.metadata.json +1 -1
- package/typings/esm5/chips/chip.d.ts +4 -2
- package/typings/esm5/chips/index.metadata.json +1 -1
- package/typings/esm5/core/common-behaviors/common-module.d.ts +2 -2
- package/typings/esm5/core/datetime/date-adapter.d.ts +1 -1
- package/typings/esm5/core/datetime/native-date-adapter.d.ts +1 -1
- package/typings/esm5/core/index.metadata.json +1 -1
- package/typings/esm5/core/ripple/ripple-renderer.d.ts +2 -2
- package/typings/esm5/core/ripple/ripple.d.ts +1 -1
- package/typings/esm5/datepicker/datepicker-intl.d.ts +2 -0
- package/typings/esm5/datepicker/index.metadata.json +1 -1
- package/typings/esm5/dialog/dialog-config.d.ts +9 -7
- package/typings/esm5/dialog/dialog-content-directives.d.ts +2 -0
- package/typings/esm5/dialog/dialog-ref.d.ts +10 -0
- package/typings/esm5/dialog/index.metadata.json +1 -1
- package/typings/esm5/form-field/form-field.d.ts +2 -0
- package/typings/esm5/form-field/index.metadata.json +1 -1
- package/typings/esm5/grid-list/index.d.ts +1 -1
- package/typings/esm5/grid-list/index.metadata.json +1 -1
- package/typings/esm5/icon/icon-registry.d.ts +17 -11
- package/typings/esm5/icon/icon.d.ts +3 -2
- package/typings/esm5/icon/index.metadata.json +1 -1
- package/typings/esm5/list/index.metadata.json +1 -1
- package/typings/esm5/menu/index.d.ts +2 -2
- package/typings/esm5/menu/index.metadata.json +1 -1
- package/typings/esm5/menu/menu-trigger.d.ts +2 -5
- package/typings/esm5/progress-spinner/index.metadata.json +1 -1
- package/typings/esm5/progress-spinner/progress-spinner.d.ts +3 -2
- package/typings/esm5/radio/index.metadata.json +1 -1
- package/typings/esm5/select/index.metadata.json +1 -1
- package/typings/esm5/select/select.d.ts +2 -0
- package/typings/esm5/slide-toggle/index.metadata.json +1 -1
- package/typings/esm5/slider/index.metadata.json +1 -1
- package/typings/esm5/slider/slider.d.ts +2 -2
- package/typings/esm5/snack-bar/index.metadata.json +1 -1
- package/typings/esm5/sort/index.metadata.json +1 -1
- package/typings/esm5/table/index.metadata.json +1 -1
- package/typings/esm5/table/table-data-source.d.ts +5 -0
- package/typings/esm5/tabs/index.d.ts +2 -2
- package/typings/esm5/tabs/index.metadata.json +1 -1
- package/typings/esm5/tabs/paginated-tab-header.d.ts +8 -5
- package/typings/esm5/tabs/public-api.d.ts +4 -4
- package/typings/esm5/tabs/tab-body.d.ts +11 -3
- package/typings/esm5/tabs/tab-group.d.ts +24 -11
- package/typings/esm5/tabs/tab-header.d.ts +12 -5
- package/typings/esm5/tabs/tab-nav-bar/tab-nav-bar.d.ts +38 -19
- package/typings/esm5/tooltip/index.metadata.json +1 -1
- package/typings/form-field/form-field.d.ts +2 -0
- package/typings/form-field/index.metadata.json +1 -1
- package/typings/grid-list/index.d.ts +1 -1
- package/typings/grid-list/index.metadata.json +1 -1
- package/typings/icon/icon-registry.d.ts +17 -11
- package/typings/icon/icon.d.ts +3 -2
- package/typings/icon/index.metadata.json +1 -1
- package/typings/list/index.metadata.json +1 -1
- package/typings/menu/index.d.ts +2 -2
- package/typings/menu/index.metadata.json +1 -1
- package/typings/menu/menu-trigger.d.ts +2 -5
- package/typings/progress-spinner/index.metadata.json +1 -1
- package/typings/progress-spinner/progress-spinner.d.ts +3 -2
- package/typings/radio/index.metadata.json +1 -1
- package/typings/select/index.metadata.json +1 -1
- package/typings/select/select.d.ts +2 -0
- package/typings/slide-toggle/index.metadata.json +1 -1
- package/typings/slider/index.metadata.json +1 -1
- package/typings/slider/slider.d.ts +2 -2
- package/typings/snack-bar/index.metadata.json +1 -1
- package/typings/sort/index.metadata.json +1 -1
- package/typings/table/index.metadata.json +1 -1
- package/typings/table/table-data-source.d.ts +5 -0
- package/typings/tabs/index.d.ts +2 -2
- package/typings/tabs/index.metadata.json +1 -1
- package/typings/tabs/paginated-tab-header.d.ts +8 -5
- package/typings/tabs/public-api.d.ts +4 -4
- package/typings/tabs/tab-body.d.ts +11 -3
- package/typings/tabs/tab-group.d.ts +24 -11
- package/typings/tabs/tab-header.d.ts +12 -5
- package/typings/tabs/tab-nav-bar/tab-nav-bar.d.ts +38 -19
- package/typings/tooltip/index.metadata.json +1 -1
package/esm2015/tabs.js
CHANGED
|
@@ -13,7 +13,7 @@ import { Subject, Subscription, merge, of, timer, fromEvent } from 'rxjs';
|
|
|
13
13
|
import { animate, state, style, transition, trigger } from '@angular/animations';
|
|
14
14
|
import { Directionality } from '@angular/cdk/bidi';
|
|
15
15
|
import { startWith, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
|
16
|
-
import {
|
|
16
|
+
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
|
|
17
17
|
import { ViewportRuler } from '@angular/cdk/scrolling';
|
|
18
18
|
import { FocusKeyManager, FocusMonitor, A11yModule } from '@angular/cdk/a11y';
|
|
19
19
|
import { END, ENTER, HOME, SPACE, hasModifierKey } from '@angular/cdk/keycodes';
|
|
@@ -380,10 +380,12 @@ MatTabBodyPortal.ctorParameters = () => [
|
|
|
380
380
|
() => MatTabBody)),] }] }
|
|
381
381
|
];
|
|
382
382
|
/**
|
|
383
|
-
*
|
|
383
|
+
* Base class with all of the `MatTabBody` functionality.
|
|
384
384
|
* \@docs-private
|
|
385
|
+
* @abstract
|
|
385
386
|
*/
|
|
386
|
-
class
|
|
387
|
+
// tslint:disable-next-line:class-name
|
|
388
|
+
class _MatTabBodyBase {
|
|
387
389
|
/**
|
|
388
390
|
* @param {?} _elementRef
|
|
389
391
|
* @param {?} _dir
|
|
@@ -542,196 +544,166 @@ class MatTabBody {
|
|
|
542
544
|
return 'right-origin-center';
|
|
543
545
|
}
|
|
544
546
|
}
|
|
545
|
-
|
|
546
|
-
{ type:
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
encapsulation: ViewEncapsulation.None,
|
|
550
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
551
|
-
animations: [matTabsAnimations.translateTab],
|
|
552
|
-
host: {
|
|
553
|
-
'class': 'mat-tab-body',
|
|
554
|
-
},
|
|
547
|
+
_MatTabBodyBase.decorators = [
|
|
548
|
+
{ type: Directive, args: [{
|
|
549
|
+
// TODO(crisbeto): this selector can be removed when we update to Angular 9.0.
|
|
550
|
+
selector: 'do-not-use-abstract-mat-tab-body-base'
|
|
555
551
|
},] },
|
|
556
552
|
];
|
|
557
553
|
/** @nocollapse */
|
|
558
|
-
|
|
554
|
+
_MatTabBodyBase.ctorParameters = () => [
|
|
559
555
|
{ type: ElementRef },
|
|
560
556
|
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
561
557
|
{ type: ChangeDetectorRef }
|
|
562
558
|
];
|
|
563
|
-
|
|
559
|
+
_MatTabBodyBase.propDecorators = {
|
|
564
560
|
_onCentering: [{ type: Output }],
|
|
565
561
|
_beforeCentering: [{ type: Output }],
|
|
566
562
|
_afterLeavingCenter: [{ type: Output }],
|
|
567
563
|
_onCentered: [{ type: Output }],
|
|
568
|
-
_portalHost: [{ type: ViewChild, args: [PortalHostDirective, { static: false },] }],
|
|
569
564
|
_content: [{ type: Input, args: ['content',] }],
|
|
570
565
|
origin: [{ type: Input }],
|
|
571
566
|
animationDuration: [{ type: Input }],
|
|
572
567
|
position: [{ type: Input }]
|
|
573
568
|
};
|
|
574
|
-
|
|
575
569
|
/**
|
|
576
|
-
*
|
|
577
|
-
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
578
|
-
*/
|
|
579
|
-
// Boilerplate for applying mixins to MatTabLabelWrapper.
|
|
580
|
-
/**
|
|
581
|
-
* \@docs-private
|
|
582
|
-
*/
|
|
583
|
-
class MatTabLabelWrapperBase {
|
|
584
|
-
}
|
|
585
|
-
/** @type {?} */
|
|
586
|
-
const _MatTabLabelWrapperMixinBase = mixinDisabled(MatTabLabelWrapperBase);
|
|
587
|
-
/**
|
|
588
|
-
* Used in the `mat-tab-group` view to display tab labels.
|
|
570
|
+
* Wrapper for the contents of a tab.
|
|
589
571
|
* \@docs-private
|
|
590
572
|
*/
|
|
591
|
-
class
|
|
573
|
+
class MatTabBody extends _MatTabBodyBase {
|
|
592
574
|
/**
|
|
593
575
|
* @param {?} elementRef
|
|
576
|
+
* @param {?} dir
|
|
577
|
+
* @param {?} changeDetectorRef
|
|
594
578
|
*/
|
|
595
|
-
constructor(elementRef) {
|
|
596
|
-
super();
|
|
597
|
-
this.elementRef = elementRef;
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Sets focus on the wrapper element
|
|
601
|
-
* @return {?}
|
|
602
|
-
*/
|
|
603
|
-
focus() {
|
|
604
|
-
this.elementRef.nativeElement.focus();
|
|
605
|
-
}
|
|
606
|
-
/**
|
|
607
|
-
* @return {?}
|
|
608
|
-
*/
|
|
609
|
-
getOffsetLeft() {
|
|
610
|
-
return this.elementRef.nativeElement.offsetLeft;
|
|
611
|
-
}
|
|
612
|
-
/**
|
|
613
|
-
* @return {?}
|
|
614
|
-
*/
|
|
615
|
-
getOffsetWidth() {
|
|
616
|
-
return this.elementRef.nativeElement.offsetWidth;
|
|
579
|
+
constructor(elementRef, dir, changeDetectorRef) {
|
|
580
|
+
super(elementRef, dir, changeDetectorRef);
|
|
617
581
|
}
|
|
618
582
|
}
|
|
619
|
-
|
|
620
|
-
{ type:
|
|
621
|
-
|
|
622
|
-
|
|
583
|
+
MatTabBody.decorators = [
|
|
584
|
+
{ type: Component, args: [{selector: 'mat-tab-body',
|
|
585
|
+
template: "<div class=\"mat-tab-body-content\" #content [@translateTab]=\"{ value: _position, params: {animationDuration: animationDuration} }\" (@translateTab.start)=\"_onTranslateTabStarted($event)\" (@translateTab.done)=\"_translateTabComplete.next($event)\"><ng-template matTabBodyHost></ng-template></div>",
|
|
586
|
+
styles: [".mat-tab-body-content{height:100%;overflow:auto}.mat-tab-group-dynamic-height .mat-tab-body-content{overflow:hidden}"],
|
|
587
|
+
encapsulation: ViewEncapsulation.None,
|
|
588
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
589
|
+
animations: [matTabsAnimations.translateTab],
|
|
623
590
|
host: {
|
|
624
|
-
'
|
|
625
|
-
'[attr.aria-disabled]': '!!disabled',
|
|
591
|
+
'class': 'mat-tab-body',
|
|
626
592
|
}
|
|
627
593
|
},] },
|
|
628
594
|
];
|
|
629
595
|
/** @nocollapse */
|
|
630
|
-
|
|
631
|
-
{ type: ElementRef }
|
|
596
|
+
MatTabBody.ctorParameters = () => [
|
|
597
|
+
{ type: ElementRef },
|
|
598
|
+
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
599
|
+
{ type: ChangeDetectorRef }
|
|
632
600
|
];
|
|
601
|
+
MatTabBody.propDecorators = {
|
|
602
|
+
_portalHost: [{ type: ViewChild, args: [PortalHostDirective, { static: false },] }]
|
|
603
|
+
};
|
|
633
604
|
|
|
634
605
|
/**
|
|
635
606
|
* @fileoverview added by tsickle
|
|
636
607
|
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
637
608
|
*/
|
|
638
609
|
/**
|
|
639
|
-
*
|
|
610
|
+
* Used to generate unique ID's for each tab component
|
|
640
611
|
* @type {?}
|
|
641
612
|
*/
|
|
642
|
-
|
|
613
|
+
let nextId = 0;
|
|
643
614
|
/**
|
|
644
|
-
*
|
|
645
|
-
* provide a small affordance to the label next to it.
|
|
646
|
-
* @type {?}
|
|
615
|
+
* A simple change event emitted on focus or selection changes.
|
|
647
616
|
*/
|
|
648
|
-
|
|
617
|
+
class MatTabChangeEvent {
|
|
618
|
+
}
|
|
649
619
|
/**
|
|
650
|
-
*
|
|
651
|
-
* Set a little conservatively in order to handle fake events dispatched on touch devices.
|
|
620
|
+
* Injection token that can be used to provide the default options the tabs module.
|
|
652
621
|
* @type {?}
|
|
653
622
|
*/
|
|
654
|
-
const
|
|
623
|
+
const MAT_TABS_CONFIG = new InjectionToken('MAT_TABS_CONFIG');
|
|
624
|
+
// Boilerplate for applying mixins to MatTabGroup.
|
|
655
625
|
/**
|
|
656
|
-
*
|
|
657
|
-
* while the user is holding their pointer.
|
|
658
|
-
* @type {?}
|
|
626
|
+
* \@docs-private
|
|
659
627
|
*/
|
|
660
|
-
|
|
628
|
+
class MatTabGroupMixinBase {
|
|
629
|
+
/**
|
|
630
|
+
* @param {?} _elementRef
|
|
631
|
+
*/
|
|
632
|
+
constructor(_elementRef) {
|
|
633
|
+
this._elementRef = _elementRef;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
/** @type {?} */
|
|
637
|
+
const _MatTabGroupMixinBase = mixinColor(mixinDisableRipple(MatTabGroupMixinBase), 'primary');
|
|
661
638
|
/**
|
|
662
|
-
* Base class
|
|
639
|
+
* Base class with all of the `MatTabGroupBase` functionality.
|
|
640
|
+
* \@docs-private
|
|
663
641
|
* @abstract
|
|
664
642
|
*/
|
|
665
|
-
class
|
|
643
|
+
// tslint:disable-next-line:class-name
|
|
644
|
+
class _MatTabGroupBase extends _MatTabGroupMixinBase {
|
|
666
645
|
/**
|
|
667
|
-
* @param {?}
|
|
646
|
+
* @param {?} elementRef
|
|
668
647
|
* @param {?} _changeDetectorRef
|
|
669
|
-
* @param {
|
|
670
|
-
* @param {?} _dir
|
|
671
|
-
* @param {?} _ngZone
|
|
672
|
-
* @param {?=} _platform
|
|
648
|
+
* @param {?=} defaultConfig
|
|
673
649
|
* @param {?=} _animationMode
|
|
674
650
|
*/
|
|
675
|
-
constructor(
|
|
676
|
-
|
|
651
|
+
constructor(elementRef, _changeDetectorRef, defaultConfig, _animationMode) {
|
|
652
|
+
super(elementRef);
|
|
677
653
|
this._changeDetectorRef = _changeDetectorRef;
|
|
678
|
-
this._viewportRuler = _viewportRuler;
|
|
679
|
-
this._dir = _dir;
|
|
680
|
-
this._ngZone = _ngZone;
|
|
681
|
-
this._platform = _platform;
|
|
682
654
|
this._animationMode = _animationMode;
|
|
683
655
|
/**
|
|
684
|
-
* The
|
|
656
|
+
* The tab index that should be selected after the content has been checked.
|
|
685
657
|
*/
|
|
686
|
-
this.
|
|
658
|
+
this._indexToSelect = 0;
|
|
687
659
|
/**
|
|
688
|
-
*
|
|
660
|
+
* Snapshot of the height of the tab body wrapper before another tab is activated.
|
|
689
661
|
*/
|
|
690
|
-
this.
|
|
662
|
+
this._tabBodyWrapperHeight = 0;
|
|
691
663
|
/**
|
|
692
|
-
*
|
|
664
|
+
* Subscription to tabs being added/removed.
|
|
693
665
|
*/
|
|
694
|
-
this.
|
|
666
|
+
this._tabsSubscription = Subscription.EMPTY;
|
|
695
667
|
/**
|
|
696
|
-
*
|
|
668
|
+
* Subscription to changes in the tab labels.
|
|
697
669
|
*/
|
|
698
|
-
this.
|
|
670
|
+
this._tabLabelSubscription = Subscription.EMPTY;
|
|
671
|
+
this._dynamicHeight = false;
|
|
672
|
+
this._selectedIndex = null;
|
|
699
673
|
/**
|
|
700
|
-
*
|
|
674
|
+
* Position of the tab header.
|
|
701
675
|
*/
|
|
702
|
-
this.
|
|
676
|
+
this.headerPosition = 'above';
|
|
703
677
|
/**
|
|
704
|
-
*
|
|
678
|
+
* Output to enable support for two-way binding on `[(selectedIndex)]`
|
|
705
679
|
*/
|
|
706
|
-
this.
|
|
680
|
+
this.selectedIndexChange = new EventEmitter();
|
|
707
681
|
/**
|
|
708
|
-
*
|
|
682
|
+
* Event emitted when focus has changed within a tab group.
|
|
709
683
|
*/
|
|
710
|
-
this.
|
|
711
|
-
this._selectedIndex = 0;
|
|
684
|
+
this.focusChange = new EventEmitter();
|
|
712
685
|
/**
|
|
713
|
-
* Event emitted when the
|
|
686
|
+
* Event emitted when the body animation has completed
|
|
714
687
|
*/
|
|
715
|
-
this.
|
|
688
|
+
this.animationDone = new EventEmitter();
|
|
716
689
|
/**
|
|
717
|
-
* Event emitted when
|
|
718
|
-
*/
|
|
719
|
-
this.indexFocused = new EventEmitter();
|
|
720
|
-
// Bind the `mouseleave` event on the outside since it doesn't change anything in the view.
|
|
721
|
-
_ngZone.runOutsideAngular((/**
|
|
722
|
-
* @return {?}
|
|
690
|
+
* Event emitted when the tab selection has changed.
|
|
723
691
|
*/
|
|
724
|
-
()
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
* @return {?}
|
|
729
|
-
*/
|
|
730
|
-
() => {
|
|
731
|
-
this._stopInterval();
|
|
732
|
-
}));
|
|
733
|
-
}));
|
|
692
|
+
this.selectedTabChange = new EventEmitter(true);
|
|
693
|
+
this._groupId = nextId++;
|
|
694
|
+
this.animationDuration = defaultConfig && defaultConfig.animationDuration ?
|
|
695
|
+
defaultConfig.animationDuration : '500ms';
|
|
734
696
|
}
|
|
697
|
+
/**
|
|
698
|
+
* Whether the tab group should grow to the size of the active tab.
|
|
699
|
+
* @return {?}
|
|
700
|
+
*/
|
|
701
|
+
get dynamicHeight() { return this._dynamicHeight; }
|
|
702
|
+
/**
|
|
703
|
+
* @param {?} value
|
|
704
|
+
* @return {?}
|
|
705
|
+
*/
|
|
706
|
+
set dynamicHeight(value) { this._dynamicHeight = coerceBooleanProperty(value); }
|
|
735
707
|
/**
|
|
736
708
|
* The index of the active tab.
|
|
737
709
|
* @return {?}
|
|
@@ -742,972 +714,1109 @@ class MatPaginatedTabHeader {
|
|
|
742
714
|
* @return {?}
|
|
743
715
|
*/
|
|
744
716
|
set selectedIndex(value) {
|
|
745
|
-
|
|
746
|
-
if (this._selectedIndex != value) {
|
|
747
|
-
this._selectedIndexChanged = true;
|
|
748
|
-
this._selectedIndex = value;
|
|
749
|
-
if (this._keyManager) {
|
|
750
|
-
this._keyManager.updateActiveItemIndex(value);
|
|
751
|
-
}
|
|
752
|
-
}
|
|
717
|
+
this._indexToSelect = coerceNumberProperty(value, null);
|
|
753
718
|
}
|
|
754
719
|
/**
|
|
720
|
+
* Duration for the tab animation. Will be normalized to milliseconds if no units are set.
|
|
755
721
|
* @return {?}
|
|
756
722
|
*/
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
() => {
|
|
765
|
-
this._handlePaginatorPress('before');
|
|
766
|
-
}));
|
|
767
|
-
fromEvent(this._nextPaginator.nativeElement, 'touchstart', passiveEventListenerOptions)
|
|
768
|
-
.pipe(takeUntil(this._destroyed))
|
|
769
|
-
.subscribe((/**
|
|
770
|
-
* @return {?}
|
|
771
|
-
*/
|
|
772
|
-
() => {
|
|
773
|
-
this._handlePaginatorPress('after');
|
|
774
|
-
}));
|
|
723
|
+
get animationDuration() { return this._animationDuration; }
|
|
724
|
+
/**
|
|
725
|
+
* @param {?} value
|
|
726
|
+
* @return {?}
|
|
727
|
+
*/
|
|
728
|
+
set animationDuration(value) {
|
|
729
|
+
this._animationDuration = /^\d+$/.test(value) ? value + 'ms' : value;
|
|
775
730
|
}
|
|
776
731
|
/**
|
|
732
|
+
* Background color of the tab group.
|
|
777
733
|
* @return {?}
|
|
778
734
|
*/
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
735
|
+
get backgroundColor() { return this._backgroundColor; }
|
|
736
|
+
/**
|
|
737
|
+
* @param {?} value
|
|
738
|
+
* @return {?}
|
|
739
|
+
*/
|
|
740
|
+
set backgroundColor(value) {
|
|
782
741
|
/** @type {?} */
|
|
783
|
-
const
|
|
742
|
+
const nativeElement = this._elementRef.nativeElement;
|
|
743
|
+
nativeElement.classList.remove(`mat-background-${this.backgroundColor}`);
|
|
744
|
+
if (value) {
|
|
745
|
+
nativeElement.classList.add(`mat-background-${value}`);
|
|
746
|
+
}
|
|
747
|
+
this._backgroundColor = value;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* After the content is checked, this component knows what tabs have been defined
|
|
751
|
+
* and what the selected index should be. This is where we can know exactly what position
|
|
752
|
+
* each tab should be in according to the new selected index, and additionally we know how
|
|
753
|
+
* a new selected tab should transition in (from the left or right).
|
|
754
|
+
* @return {?}
|
|
755
|
+
*/
|
|
756
|
+
ngAfterContentChecked() {
|
|
757
|
+
// Don't clamp the `indexToSelect` immediately in the setter because it can happen that
|
|
758
|
+
// the amount of tabs changes before the actual change detection runs.
|
|
784
759
|
/** @type {?} */
|
|
785
|
-
const
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
()
|
|
789
|
-
|
|
790
|
-
this.
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
760
|
+
const indexToSelect = this._indexToSelect = this._clampTabIndex(this._indexToSelect);
|
|
761
|
+
// If there is a change in selected index, emit a change event. Should not trigger if
|
|
762
|
+
// the selected index has not yet been initialized.
|
|
763
|
+
if (this._selectedIndex != indexToSelect) {
|
|
764
|
+
/** @type {?} */
|
|
765
|
+
const isFirstRun = this._selectedIndex == null;
|
|
766
|
+
if (!isFirstRun) {
|
|
767
|
+
this.selectedTabChange.emit(this._createChangeEvent(indexToSelect));
|
|
768
|
+
}
|
|
769
|
+
// Changing these values after change detection has run
|
|
770
|
+
// since the checked content may contain references to them.
|
|
771
|
+
Promise.resolve().then((/**
|
|
772
|
+
* @return {?}
|
|
773
|
+
*/
|
|
774
|
+
() => {
|
|
775
|
+
this._tabs.forEach((/**
|
|
776
|
+
* @param {?} tab
|
|
777
|
+
* @param {?} index
|
|
778
|
+
* @return {?}
|
|
779
|
+
*/
|
|
780
|
+
(tab, index) => tab.isActive = index === indexToSelect));
|
|
781
|
+
if (!isFirstRun) {
|
|
782
|
+
this.selectedIndexChange.emit(indexToSelect);
|
|
783
|
+
}
|
|
784
|
+
}));
|
|
785
|
+
}
|
|
786
|
+
// Setup the position for each tab and optionally setup an origin on the next selected tab.
|
|
787
|
+
this._tabs.forEach((/**
|
|
788
|
+
* @param {?} tab
|
|
789
|
+
* @param {?} index
|
|
813
790
|
* @return {?}
|
|
814
791
|
*/
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
792
|
+
(tab, index) => {
|
|
793
|
+
tab.position = index - indexToSelect;
|
|
794
|
+
// If there is already a selected tab, then set up an origin for the next selected tab
|
|
795
|
+
// if it doesn't have one already.
|
|
796
|
+
if (this._selectedIndex != null && tab.position == 0 && !tab.origin) {
|
|
797
|
+
tab.origin = indexToSelect - this._selectedIndex;
|
|
798
|
+
}
|
|
818
799
|
}));
|
|
800
|
+
if (this._selectedIndex !== indexToSelect) {
|
|
801
|
+
this._selectedIndex = indexToSelect;
|
|
802
|
+
this._changeDetectorRef.markForCheck();
|
|
803
|
+
}
|
|
819
804
|
}
|
|
820
805
|
/**
|
|
821
806
|
* @return {?}
|
|
822
807
|
*/
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
this.
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
808
|
+
ngAfterContentInit() {
|
|
809
|
+
this._subscribeToTabLabels();
|
|
810
|
+
// Subscribe to changes in the amount of tabs, in order to be
|
|
811
|
+
// able to re-render the content as new tabs are added or removed.
|
|
812
|
+
this._tabsSubscription = this._tabs.changes.subscribe((/**
|
|
813
|
+
* @return {?}
|
|
814
|
+
*/
|
|
815
|
+
() => {
|
|
816
|
+
/** @type {?} */
|
|
817
|
+
const indexToSelect = this._clampTabIndex(this._indexToSelect);
|
|
818
|
+
// Maintain the previously-selected tab if a new tab is added or removed and there is no
|
|
819
|
+
// explicit change that selects a different tab.
|
|
820
|
+
if (indexToSelect === this._selectedIndex) {
|
|
821
|
+
/** @type {?} */
|
|
822
|
+
const tabs = this._tabs.toArray();
|
|
823
|
+
for (let i = 0; i < tabs.length; i++) {
|
|
824
|
+
if (tabs[i].isActive) {
|
|
825
|
+
// Assign both to the `_indexToSelect` and `_selectedIndex` so we don't fire a changed
|
|
826
|
+
// event, otherwise the consumer may end up in an infinite loop in some edge cases like
|
|
827
|
+
// adding a tab within the `selectedIndexChange` event.
|
|
828
|
+
this._indexToSelect = this._selectedIndex = i;
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
this._subscribeToTabLabels();
|
|
844
834
|
this._changeDetectorRef.markForCheck();
|
|
845
|
-
}
|
|
835
|
+
}));
|
|
846
836
|
}
|
|
847
837
|
/**
|
|
848
838
|
* @return {?}
|
|
849
839
|
*/
|
|
850
840
|
ngOnDestroy() {
|
|
851
|
-
this.
|
|
852
|
-
this.
|
|
853
|
-
this._stopScrolling.complete();
|
|
841
|
+
this._tabsSubscription.unsubscribe();
|
|
842
|
+
this._tabLabelSubscription.unsubscribe();
|
|
854
843
|
}
|
|
855
844
|
/**
|
|
856
|
-
*
|
|
857
|
-
* @param {?} event
|
|
845
|
+
* Re-aligns the ink bar to the selected tab element.
|
|
858
846
|
* @return {?}
|
|
859
847
|
*/
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
return;
|
|
864
|
-
}
|
|
865
|
-
switch (event.keyCode) {
|
|
866
|
-
case HOME:
|
|
867
|
-
this._keyManager.setFirstItemActive();
|
|
868
|
-
event.preventDefault();
|
|
869
|
-
break;
|
|
870
|
-
case END:
|
|
871
|
-
this._keyManager.setLastItemActive();
|
|
872
|
-
event.preventDefault();
|
|
873
|
-
break;
|
|
874
|
-
case ENTER:
|
|
875
|
-
case SPACE:
|
|
876
|
-
this.selectFocusedIndex.emit(this.focusIndex);
|
|
877
|
-
this._itemSelected(event);
|
|
878
|
-
break;
|
|
879
|
-
default:
|
|
880
|
-
this._keyManager.onKeydown(event);
|
|
848
|
+
realignInkBar() {
|
|
849
|
+
if (this._tabHeader) {
|
|
850
|
+
this._tabHeader._alignInkBarToSelectedTab();
|
|
881
851
|
}
|
|
882
852
|
}
|
|
883
853
|
/**
|
|
884
|
-
*
|
|
854
|
+
* @param {?} index
|
|
885
855
|
* @return {?}
|
|
886
856
|
*/
|
|
887
|
-
|
|
857
|
+
_focusChanged(index) {
|
|
858
|
+
this.focusChange.emit(this._createChangeEvent(index));
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* @private
|
|
862
|
+
* @param {?} index
|
|
863
|
+
* @return {?}
|
|
864
|
+
*/
|
|
865
|
+
_createChangeEvent(index) {
|
|
888
866
|
/** @type {?} */
|
|
889
|
-
const
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
if (textContent !== this._currentTextContent) {
|
|
894
|
-
this._currentTextContent = textContent || '';
|
|
895
|
-
// The content observer runs outside the `NgZone` by default, which
|
|
896
|
-
// means that we need to bring the callback back in ourselves.
|
|
897
|
-
this._ngZone.run((/**
|
|
898
|
-
* @return {?}
|
|
899
|
-
*/
|
|
900
|
-
() => {
|
|
901
|
-
this.updatePagination();
|
|
902
|
-
this._alignInkBarToSelectedTab();
|
|
903
|
-
this._changeDetectorRef.markForCheck();
|
|
904
|
-
}));
|
|
867
|
+
const event = new MatTabChangeEvent;
|
|
868
|
+
event.index = index;
|
|
869
|
+
if (this._tabs && this._tabs.length) {
|
|
870
|
+
event.tab = this._tabs.toArray()[index];
|
|
905
871
|
}
|
|
872
|
+
return event;
|
|
906
873
|
}
|
|
907
874
|
/**
|
|
908
|
-
*
|
|
909
|
-
*
|
|
910
|
-
*
|
|
911
|
-
*
|
|
912
|
-
*
|
|
875
|
+
* Subscribes to changes in the tab labels. This is needed, because the \@Input for the label is
|
|
876
|
+
* on the MatTab component, whereas the data binding is inside the MatTabGroup. In order for the
|
|
877
|
+
* binding to be updated, we need to subscribe to changes in it and trigger change detection
|
|
878
|
+
* manually.
|
|
879
|
+
* @private
|
|
913
880
|
* @return {?}
|
|
914
881
|
*/
|
|
915
|
-
|
|
916
|
-
this.
|
|
917
|
-
|
|
918
|
-
|
|
882
|
+
_subscribeToTabLabels() {
|
|
883
|
+
if (this._tabLabelSubscription) {
|
|
884
|
+
this._tabLabelSubscription.unsubscribe();
|
|
885
|
+
}
|
|
886
|
+
this._tabLabelSubscription = merge(...this._tabs.map((/**
|
|
887
|
+
* @param {?} tab
|
|
888
|
+
* @return {?}
|
|
889
|
+
*/
|
|
890
|
+
tab => tab._stateChanges)))
|
|
891
|
+
.subscribe((/**
|
|
892
|
+
* @return {?}
|
|
893
|
+
*/
|
|
894
|
+
() => this._changeDetectorRef.markForCheck()));
|
|
919
895
|
}
|
|
920
896
|
/**
|
|
921
|
-
*
|
|
897
|
+
* Clamps the given index to the bounds of 0 and the tabs length.
|
|
898
|
+
* @private
|
|
899
|
+
* @param {?} index
|
|
922
900
|
* @return {?}
|
|
923
901
|
*/
|
|
924
|
-
|
|
925
|
-
|
|
902
|
+
_clampTabIndex(index) {
|
|
903
|
+
// Note the `|| 0`, which ensures that values like NaN can't get through
|
|
904
|
+
// and which would otherwise throw the component into an infinite loop
|
|
905
|
+
// (since Math.max(NaN, 0) === NaN).
|
|
906
|
+
return Math.min(this._tabs.length - 1, Math.max(index || 0, 0));
|
|
926
907
|
}
|
|
927
908
|
/**
|
|
928
|
-
*
|
|
929
|
-
* @param {?}
|
|
909
|
+
* Returns a unique id for each tab label element
|
|
910
|
+
* @param {?} i
|
|
930
911
|
* @return {?}
|
|
931
912
|
*/
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
return;
|
|
935
|
-
}
|
|
936
|
-
this._keyManager.setActiveItem(value);
|
|
913
|
+
_getTabLabelId(i) {
|
|
914
|
+
return `mat-tab-label-${this._groupId}-${i}`;
|
|
937
915
|
}
|
|
938
916
|
/**
|
|
939
|
-
*
|
|
940
|
-
*
|
|
941
|
-
* @param {?} index
|
|
917
|
+
* Returns a unique id for each tab content element
|
|
918
|
+
* @param {?} i
|
|
942
919
|
* @return {?}
|
|
943
920
|
*/
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
return true;
|
|
947
|
-
}
|
|
948
|
-
/** @type {?} */
|
|
949
|
-
const tab = this._items ? this._items.toArray()[index] : null;
|
|
950
|
-
return !!tab && !tab.disabled;
|
|
921
|
+
_getTabContentId(i) {
|
|
922
|
+
return `mat-tab-content-${this._groupId}-${i}`;
|
|
951
923
|
}
|
|
952
924
|
/**
|
|
953
|
-
* Sets
|
|
954
|
-
*
|
|
955
|
-
* @param {?}
|
|
925
|
+
* Sets the height of the body wrapper to the height of the activating tab if dynamic
|
|
926
|
+
* height property is true.
|
|
927
|
+
* @param {?} tabHeight
|
|
956
928
|
* @return {?}
|
|
957
929
|
*/
|
|
958
|
-
|
|
959
|
-
if (this.
|
|
960
|
-
|
|
930
|
+
_setTabBodyWrapperHeight(tabHeight) {
|
|
931
|
+
if (!this._dynamicHeight || !this._tabBodyWrapperHeight) {
|
|
932
|
+
return;
|
|
961
933
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
/** @type {?} */
|
|
970
|
-
const dir = this._getLayoutDirection();
|
|
971
|
-
if (dir == 'ltr') {
|
|
972
|
-
containerEl.scrollLeft = 0;
|
|
973
|
-
}
|
|
974
|
-
else {
|
|
975
|
-
containerEl.scrollLeft = containerEl.scrollWidth - containerEl.offsetWidth;
|
|
976
|
-
}
|
|
934
|
+
/** @type {?} */
|
|
935
|
+
const wrapper = this._tabBodyWrapper.nativeElement;
|
|
936
|
+
wrapper.style.height = this._tabBodyWrapperHeight + 'px';
|
|
937
|
+
// This conditional forces the browser to paint the height so that
|
|
938
|
+
// the animation to the new height can have an origin.
|
|
939
|
+
if (this._tabBodyWrapper.nativeElement.offsetHeight) {
|
|
940
|
+
wrapper.style.height = tabHeight + 'px';
|
|
977
941
|
}
|
|
978
942
|
}
|
|
979
943
|
/**
|
|
980
|
-
*
|
|
944
|
+
* Removes the height of the tab body wrapper.
|
|
981
945
|
* @return {?}
|
|
982
946
|
*/
|
|
983
|
-
|
|
984
|
-
|
|
947
|
+
_removeTabBodyWrapperHeight() {
|
|
948
|
+
/** @type {?} */
|
|
949
|
+
const wrapper = this._tabBodyWrapper.nativeElement;
|
|
950
|
+
this._tabBodyWrapperHeight = wrapper.clientHeight;
|
|
951
|
+
wrapper.style.height = '';
|
|
952
|
+
this.animationDone.emit();
|
|
985
953
|
}
|
|
986
954
|
/**
|
|
987
|
-
*
|
|
955
|
+
* Handle click events, setting new selected index if appropriate.
|
|
956
|
+
* @param {?} tab
|
|
957
|
+
* @param {?} tabHeader
|
|
958
|
+
* @param {?} index
|
|
988
959
|
* @return {?}
|
|
989
960
|
*/
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
/** @type {?} */
|
|
994
|
-
const platform = this._platform;
|
|
995
|
-
/** @type {?} */
|
|
996
|
-
const translateX = this._getLayoutDirection() === 'ltr' ? -scrollDistance : scrollDistance;
|
|
997
|
-
// Don't use `translate3d` here because we don't want to create a new layer. A new layer
|
|
998
|
-
// seems to cause flickering and overflow in Internet Explorer. For example, the ink bar
|
|
999
|
-
// and ripples will exceed the boundaries of the visible tab bar.
|
|
1000
|
-
// See: https://github.com/angular/components/issues/10276
|
|
1001
|
-
// We round the `transform` here, because transforms with sub-pixel precision cause some
|
|
1002
|
-
// browsers to blur the content of the element.
|
|
1003
|
-
this._tabList.nativeElement.style.transform = `translateX(${Math.round(translateX)}px)`;
|
|
1004
|
-
// Setting the `transform` on IE will change the scroll offset of the parent, causing the
|
|
1005
|
-
// position to be thrown off in some cases. We have to reset it ourselves to ensure that
|
|
1006
|
-
// it doesn't get thrown off. Note that we scope it only to IE and Edge, because messing
|
|
1007
|
-
// with the scroll position throws off Chrome 71+ in RTL mode (see #14689).
|
|
1008
|
-
// @breaking-change 9.0.0 Remove null check for `platform` after it can no longer be undefined.
|
|
1009
|
-
if (platform && (platform.TRIDENT || platform.EDGE)) {
|
|
1010
|
-
this._tabListContainer.nativeElement.scrollLeft = 0;
|
|
961
|
+
_handleClick(tab, tabHeader, index) {
|
|
962
|
+
if (!tab.disabled) {
|
|
963
|
+
this.selectedIndex = tabHeader.focusIndex = index;
|
|
1011
964
|
}
|
|
1012
965
|
}
|
|
1013
966
|
/**
|
|
1014
|
-
*
|
|
1015
|
-
* @
|
|
1016
|
-
|
|
1017
|
-
get scrollDistance() { return this._scrollDistance; }
|
|
1018
|
-
/**
|
|
1019
|
-
* @param {?} value
|
|
967
|
+
* Retrieves the tabindex for the tab.
|
|
968
|
+
* @param {?} tab
|
|
969
|
+
* @param {?} idx
|
|
1020
970
|
* @return {?}
|
|
1021
971
|
*/
|
|
1022
|
-
|
|
1023
|
-
|
|
972
|
+
_getTabIndex(tab, idx) {
|
|
973
|
+
if (tab.disabled) {
|
|
974
|
+
return null;
|
|
975
|
+
}
|
|
976
|
+
return this.selectedIndex === idx ? 0 : -1;
|
|
1024
977
|
}
|
|
978
|
+
}
|
|
979
|
+
_MatTabGroupBase.decorators = [
|
|
980
|
+
{ type: Directive, args: [{
|
|
981
|
+
// TODO(crisbeto): this selector can be removed when we update to Angular 9.0.
|
|
982
|
+
selector: 'do-not-use-abstract-mat-tab-group-base'
|
|
983
|
+
},] },
|
|
984
|
+
];
|
|
985
|
+
/** @nocollapse */
|
|
986
|
+
_MatTabGroupBase.ctorParameters = () => [
|
|
987
|
+
{ type: ElementRef },
|
|
988
|
+
{ type: ChangeDetectorRef },
|
|
989
|
+
{ type: undefined, decorators: [{ type: Inject, args: [MAT_TABS_CONFIG,] }, { type: Optional }] },
|
|
990
|
+
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
|
|
991
|
+
];
|
|
992
|
+
_MatTabGroupBase.propDecorators = {
|
|
993
|
+
dynamicHeight: [{ type: Input }],
|
|
994
|
+
selectedIndex: [{ type: Input }],
|
|
995
|
+
headerPosition: [{ type: Input }],
|
|
996
|
+
animationDuration: [{ type: Input }],
|
|
997
|
+
backgroundColor: [{ type: Input }],
|
|
998
|
+
selectedIndexChange: [{ type: Output }],
|
|
999
|
+
focusChange: [{ type: Output }],
|
|
1000
|
+
animationDone: [{ type: Output }],
|
|
1001
|
+
selectedTabChange: [{ type: Output }]
|
|
1002
|
+
};
|
|
1003
|
+
/**
|
|
1004
|
+
* Material design tab-group component. Supports basic tab pairs (label + content) and includes
|
|
1005
|
+
* animated ink-bar, keyboard navigation, and screen reader.
|
|
1006
|
+
* See: https://material.io/design/components/tabs.html
|
|
1007
|
+
*/
|
|
1008
|
+
class MatTabGroup extends _MatTabGroupBase {
|
|
1025
1009
|
/**
|
|
1026
|
-
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1030
|
-
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
1031
|
-
* should be called sparingly.
|
|
1032
|
-
* @param {?} direction
|
|
1033
|
-
* @return {?}
|
|
1010
|
+
* @param {?} elementRef
|
|
1011
|
+
* @param {?} changeDetectorRef
|
|
1012
|
+
* @param {?=} defaultConfig
|
|
1013
|
+
* @param {?=} animationMode
|
|
1034
1014
|
*/
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
const viewLength = this._tabListContainer.nativeElement.offsetWidth;
|
|
1038
|
-
// Move the scroll distance one-third the length of the tab list's viewport.
|
|
1039
|
-
/** @type {?} */
|
|
1040
|
-
const scrollAmount = (direction == 'before' ? -1 : 1) * viewLength / 3;
|
|
1041
|
-
return this._scrollTo(this._scrollDistance + scrollAmount);
|
|
1015
|
+
constructor(elementRef, changeDetectorRef, defaultConfig, animationMode) {
|
|
1016
|
+
super(elementRef, changeDetectorRef, defaultConfig, animationMode);
|
|
1042
1017
|
}
|
|
1018
|
+
}
|
|
1019
|
+
MatTabGroup.decorators = [
|
|
1020
|
+
{ type: Component, args: [{selector: 'mat-tab-group',
|
|
1021
|
+
exportAs: 'matTabGroup',
|
|
1022
|
+
template: "<mat-tab-header #tabHeader [selectedIndex]=\"selectedIndex\" [disableRipple]=\"disableRipple\" (indexFocused)=\"_focusChanged($event)\" (selectFocusedIndex)=\"selectedIndex = $event\"><div class=\"mat-tab-label\" role=\"tab\" matTabLabelWrapper mat-ripple cdkMonitorElementFocus *ngFor=\"let tab of _tabs; let i = index\" [id]=\"_getTabLabelId(i)\" [attr.tabIndex]=\"_getTabIndex(tab, i)\" [attr.aria-posinset]=\"i + 1\" [attr.aria-setsize]=\"_tabs.length\" [attr.aria-controls]=\"_getTabContentId(i)\" [attr.aria-selected]=\"selectedIndex == i\" [attr.aria-label]=\"tab.ariaLabel || null\" [attr.aria-labelledby]=\"(!tab.ariaLabel && tab.ariaLabelledby) ? tab.ariaLabelledby : null\" [class.mat-tab-label-active]=\"selectedIndex == i\" [disabled]=\"tab.disabled\" [matRippleDisabled]=\"tab.disabled || disableRipple\" (click)=\"_handleClick(tab, tabHeader, i)\"><div class=\"mat-tab-label-content\"><ng-template [ngIf]=\"tab.templateLabel\"><ng-template [cdkPortalOutlet]=\"tab.templateLabel\"></ng-template></ng-template><ng-template [ngIf]=\"!tab.templateLabel\">{{tab.textLabel}}</ng-template></div></div></mat-tab-header><div class=\"mat-tab-body-wrapper\" [class._mat-animation-noopable]=\"_animationMode === 'NoopAnimations'\" #tabBodyWrapper><mat-tab-body role=\"tabpanel\" *ngFor=\"let tab of _tabs; let i = index\" [id]=\"_getTabContentId(i)\" [attr.aria-labelledby]=\"_getTabLabelId(i)\" [class.mat-tab-body-active]=\"selectedIndex == i\" [content]=\"tab.content\" [position]=\"tab.position\" [origin]=\"tab.origin\" [animationDuration]=\"animationDuration\" (_onCentered)=\"_removeTabBodyWrapperHeight()\" (_onCentering)=\"_setTabBodyWrapperHeight($event)\"></mat-tab-body></div>",
|
|
1023
|
+
styles: [".mat-tab-group{display:flex;flex-direction:column}.mat-tab-group.mat-tab-group-inverted-header{flex-direction:column-reverse}.mat-tab-label{height:48px;padding:0 24px;cursor:pointer;box-sizing:border-box;opacity:.6;min-width:160px;text-align:center;display:inline-flex;justify-content:center;align-items:center;white-space:nowrap;position:relative}.mat-tab-label:focus{outline:0}.mat-tab-label:focus:not(.mat-tab-disabled){opacity:1}@media (-ms-high-contrast:active){.mat-tab-label:focus{outline:dotted 2px}}.mat-tab-label.mat-tab-disabled{cursor:default}@media (-ms-high-contrast:active){.mat-tab-label.mat-tab-disabled{opacity:.5}}.mat-tab-label .mat-tab-label-content{display:inline-flex;justify-content:center;align-items:center;white-space:nowrap}@media (-ms-high-contrast:active){.mat-tab-label{opacity:1}}@media (max-width:599px){.mat-tab-label{padding:0 12px}}@media (max-width:959px){.mat-tab-label{padding:0 12px}}.mat-tab-group[mat-stretch-tabs]>.mat-tab-header .mat-tab-label{flex-basis:0;flex-grow:1}.mat-tab-body-wrapper{position:relative;overflow:hidden;display:flex;transition:height .5s cubic-bezier(.35,0,.25,1)}._mat-animation-noopable.mat-tab-body-wrapper{transition:none;animation:none}.mat-tab-body{top:0;left:0;right:0;bottom:0;position:absolute;display:block;overflow:hidden;flex-basis:100%}.mat-tab-body.mat-tab-body-active{position:relative;overflow-x:hidden;overflow-y:auto;z-index:1;flex-grow:1}.mat-tab-group.mat-tab-group-dynamic-height .mat-tab-body.mat-tab-body-active{overflow-y:hidden}"],
|
|
1024
|
+
encapsulation: ViewEncapsulation.None,
|
|
1025
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1026
|
+
inputs: ['color', 'disableRipple'],
|
|
1027
|
+
host: {
|
|
1028
|
+
'class': 'mat-tab-group',
|
|
1029
|
+
'[class.mat-tab-group-dynamic-height]': 'dynamicHeight',
|
|
1030
|
+
'[class.mat-tab-group-inverted-header]': 'headerPosition === "below"',
|
|
1031
|
+
},
|
|
1032
|
+
},] },
|
|
1033
|
+
];
|
|
1034
|
+
/** @nocollapse */
|
|
1035
|
+
MatTabGroup.ctorParameters = () => [
|
|
1036
|
+
{ type: ElementRef },
|
|
1037
|
+
{ type: ChangeDetectorRef },
|
|
1038
|
+
{ type: undefined, decorators: [{ type: Inject, args: [MAT_TABS_CONFIG,] }, { type: Optional }] },
|
|
1039
|
+
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
|
|
1040
|
+
];
|
|
1041
|
+
MatTabGroup.propDecorators = {
|
|
1042
|
+
_tabs: [{ type: ContentChildren, args: [MatTab,] }],
|
|
1043
|
+
_tabBodyWrapper: [{ type: ViewChild, args: ['tabBodyWrapper', { static: false },] }],
|
|
1044
|
+
_tabHeader: [{ type: ViewChild, args: ['tabHeader', { static: false },] }]
|
|
1045
|
+
};
|
|
1046
|
+
|
|
1047
|
+
/**
|
|
1048
|
+
* @fileoverview added by tsickle
|
|
1049
|
+
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1050
|
+
*/
|
|
1051
|
+
// Boilerplate for applying mixins to MatTabLabelWrapper.
|
|
1052
|
+
/**
|
|
1053
|
+
* \@docs-private
|
|
1054
|
+
*/
|
|
1055
|
+
class MatTabLabelWrapperBase {
|
|
1056
|
+
}
|
|
1057
|
+
/** @type {?} */
|
|
1058
|
+
const _MatTabLabelWrapperMixinBase = mixinDisabled(MatTabLabelWrapperBase);
|
|
1059
|
+
/**
|
|
1060
|
+
* Used in the `mat-tab-group` view to display tab labels.
|
|
1061
|
+
* \@docs-private
|
|
1062
|
+
*/
|
|
1063
|
+
class MatTabLabelWrapper extends _MatTabLabelWrapperMixinBase {
|
|
1043
1064
|
/**
|
|
1044
|
-
*
|
|
1045
|
-
* @param {?} direction
|
|
1046
|
-
* @return {?}
|
|
1065
|
+
* @param {?} elementRef
|
|
1047
1066
|
*/
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
this.
|
|
1067
|
+
constructor(elementRef) {
|
|
1068
|
+
super();
|
|
1069
|
+
this.elementRef = elementRef;
|
|
1051
1070
|
}
|
|
1052
1071
|
/**
|
|
1053
|
-
*
|
|
1054
|
-
*
|
|
1055
|
-
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
1056
|
-
* should be called sparingly.
|
|
1057
|
-
* @param {?} labelIndex
|
|
1072
|
+
* Sets focus on the wrapper element
|
|
1058
1073
|
* @return {?}
|
|
1059
1074
|
*/
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
const selectedLabel = this._items ? this._items.toArray()[labelIndex] : null;
|
|
1063
|
-
if (!selectedLabel) {
|
|
1064
|
-
return;
|
|
1065
|
-
}
|
|
1066
|
-
// The view length is the visible width of the tab labels.
|
|
1067
|
-
/** @type {?} */
|
|
1068
|
-
const viewLength = this._tabListContainer.nativeElement.offsetWidth;
|
|
1069
|
-
const { offsetLeft, offsetWidth } = selectedLabel.elementRef.nativeElement;
|
|
1070
|
-
/** @type {?} */
|
|
1071
|
-
let labelBeforePos;
|
|
1072
|
-
/** @type {?} */
|
|
1073
|
-
let labelAfterPos;
|
|
1074
|
-
if (this._getLayoutDirection() == 'ltr') {
|
|
1075
|
-
labelBeforePos = offsetLeft;
|
|
1076
|
-
labelAfterPos = labelBeforePos + offsetWidth;
|
|
1077
|
-
}
|
|
1078
|
-
else {
|
|
1079
|
-
labelAfterPos = this._tabList.nativeElement.offsetWidth - offsetLeft;
|
|
1080
|
-
labelBeforePos = labelAfterPos - offsetWidth;
|
|
1081
|
-
}
|
|
1082
|
-
/** @type {?} */
|
|
1083
|
-
const beforeVisiblePos = this.scrollDistance;
|
|
1084
|
-
/** @type {?} */
|
|
1085
|
-
const afterVisiblePos = this.scrollDistance + viewLength;
|
|
1086
|
-
if (labelBeforePos < beforeVisiblePos) {
|
|
1087
|
-
// Scroll header to move label to the before direction
|
|
1088
|
-
this.scrollDistance -= beforeVisiblePos - labelBeforePos + EXAGGERATED_OVERSCROLL;
|
|
1089
|
-
}
|
|
1090
|
-
else if (labelAfterPos > afterVisiblePos) {
|
|
1091
|
-
// Scroll header to move label to the after direction
|
|
1092
|
-
this.scrollDistance += labelAfterPos - afterVisiblePos + EXAGGERATED_OVERSCROLL;
|
|
1093
|
-
}
|
|
1075
|
+
focus() {
|
|
1076
|
+
this.elementRef.nativeElement.focus();
|
|
1094
1077
|
}
|
|
1095
1078
|
/**
|
|
1096
|
-
* Evaluate whether the pagination controls should be displayed. If the scroll width of the
|
|
1097
|
-
* tab list is wider than the size of the header container, then the pagination controls should
|
|
1098
|
-
* be shown.
|
|
1099
|
-
*
|
|
1100
|
-
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
1101
|
-
* should be called sparingly.
|
|
1102
1079
|
* @return {?}
|
|
1103
1080
|
*/
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
const isEnabled = this._tabList.nativeElement.scrollWidth > this._elementRef.nativeElement.offsetWidth;
|
|
1107
|
-
if (!isEnabled) {
|
|
1108
|
-
this.scrollDistance = 0;
|
|
1109
|
-
}
|
|
1110
|
-
if (isEnabled !== this._showPaginationControls) {
|
|
1111
|
-
this._changeDetectorRef.markForCheck();
|
|
1112
|
-
}
|
|
1113
|
-
this._showPaginationControls = isEnabled;
|
|
1081
|
+
getOffsetLeft() {
|
|
1082
|
+
return this.elementRef.nativeElement.offsetLeft;
|
|
1114
1083
|
}
|
|
1115
1084
|
/**
|
|
1116
|
-
* Evaluate whether the before and after controls should be enabled or disabled.
|
|
1117
|
-
* If the header is at the beginning of the list (scroll distance is equal to 0) then disable the
|
|
1118
|
-
* before button. If the header is at the end of the list (scroll distance is equal to the
|
|
1119
|
-
* maximum distance we can scroll), then disable the after button.
|
|
1120
|
-
*
|
|
1121
|
-
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
1122
|
-
* should be called sparingly.
|
|
1123
1085
|
* @return {?}
|
|
1124
1086
|
*/
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
this._disableScrollBefore = this.scrollDistance == 0;
|
|
1128
|
-
this._disableScrollAfter = this.scrollDistance == this._getMaxScrollDistance();
|
|
1129
|
-
this._changeDetectorRef.markForCheck();
|
|
1087
|
+
getOffsetWidth() {
|
|
1088
|
+
return this.elementRef.nativeElement.offsetWidth;
|
|
1130
1089
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1090
|
+
}
|
|
1091
|
+
MatTabLabelWrapper.decorators = [
|
|
1092
|
+
{ type: Directive, args: [{
|
|
1093
|
+
selector: '[matTabLabelWrapper]',
|
|
1094
|
+
inputs: ['disabled'],
|
|
1095
|
+
host: {
|
|
1096
|
+
'[class.mat-tab-disabled]': 'disabled',
|
|
1097
|
+
'[attr.aria-disabled]': '!!disabled',
|
|
1098
|
+
}
|
|
1099
|
+
},] },
|
|
1100
|
+
];
|
|
1101
|
+
/** @nocollapse */
|
|
1102
|
+
MatTabLabelWrapper.ctorParameters = () => [
|
|
1103
|
+
{ type: ElementRef }
|
|
1104
|
+
];
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* @fileoverview added by tsickle
|
|
1108
|
+
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1109
|
+
*/
|
|
1110
|
+
/**
|
|
1111
|
+
* Config used to bind passive event listeners
|
|
1112
|
+
* @type {?}
|
|
1113
|
+
*/
|
|
1114
|
+
const passiveEventListenerOptions = (/** @type {?} */ (normalizePassiveListenerOptions({ passive: true })));
|
|
1115
|
+
/**
|
|
1116
|
+
* The distance in pixels that will be overshot when scrolling a tab label into view. This helps
|
|
1117
|
+
* provide a small affordance to the label next to it.
|
|
1118
|
+
* @type {?}
|
|
1119
|
+
*/
|
|
1120
|
+
const EXAGGERATED_OVERSCROLL = 60;
|
|
1121
|
+
/**
|
|
1122
|
+
* Amount of milliseconds to wait before starting to scroll the header automatically.
|
|
1123
|
+
* Set a little conservatively in order to handle fake events dispatched on touch devices.
|
|
1124
|
+
* @type {?}
|
|
1125
|
+
*/
|
|
1126
|
+
const HEADER_SCROLL_DELAY = 650;
|
|
1127
|
+
/**
|
|
1128
|
+
* Interval in milliseconds at which to scroll the header
|
|
1129
|
+
* while the user is holding their pointer.
|
|
1130
|
+
* @type {?}
|
|
1131
|
+
*/
|
|
1132
|
+
const HEADER_SCROLL_INTERVAL = 100;
|
|
1133
|
+
/**
|
|
1134
|
+
* Base class for a tab header that supported pagination.
|
|
1135
|
+
* \@docs-private
|
|
1136
|
+
* @abstract
|
|
1137
|
+
*/
|
|
1138
|
+
class MatPaginatedTabHeader {
|
|
1139
|
+
/**
|
|
1140
|
+
* @param {?} _elementRef
|
|
1141
|
+
* @param {?} _changeDetectorRef
|
|
1142
|
+
* @param {?} _viewportRuler
|
|
1143
|
+
* @param {?} _dir
|
|
1144
|
+
* @param {?} _ngZone
|
|
1145
|
+
* @param {?=} _platform
|
|
1146
|
+
* @param {?=} _animationMode
|
|
1138
1147
|
*/
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1148
|
+
constructor(_elementRef, _changeDetectorRef, _viewportRuler, _dir, _ngZone, _platform, _animationMode) {
|
|
1149
|
+
this._elementRef = _elementRef;
|
|
1150
|
+
this._changeDetectorRef = _changeDetectorRef;
|
|
1151
|
+
this._viewportRuler = _viewportRuler;
|
|
1152
|
+
this._dir = _dir;
|
|
1153
|
+
this._ngZone = _ngZone;
|
|
1154
|
+
this._platform = _platform;
|
|
1155
|
+
this._animationMode = _animationMode;
|
|
1156
|
+
/**
|
|
1157
|
+
* The distance in pixels that the tab labels should be translated to the left.
|
|
1158
|
+
*/
|
|
1159
|
+
this._scrollDistance = 0;
|
|
1160
|
+
/**
|
|
1161
|
+
* Whether the header should scroll to the selected index after the view has been checked.
|
|
1162
|
+
*/
|
|
1163
|
+
this._selectedIndexChanged = false;
|
|
1164
|
+
/**
|
|
1165
|
+
* Emits when the component is destroyed.
|
|
1166
|
+
*/
|
|
1167
|
+
this._destroyed = new Subject();
|
|
1168
|
+
/**
|
|
1169
|
+
* Whether the controls for pagination should be displayed
|
|
1170
|
+
*/
|
|
1171
|
+
this._showPaginationControls = false;
|
|
1172
|
+
/**
|
|
1173
|
+
* Whether the tab list can be scrolled more towards the end of the tab label list.
|
|
1174
|
+
*/
|
|
1175
|
+
this._disableScrollAfter = true;
|
|
1176
|
+
/**
|
|
1177
|
+
* Whether the tab list can be scrolled more towards the beginning of the tab label list.
|
|
1178
|
+
*/
|
|
1179
|
+
this._disableScrollBefore = true;
|
|
1180
|
+
/**
|
|
1181
|
+
* Stream that will stop the automated scrolling.
|
|
1182
|
+
*/
|
|
1183
|
+
this._stopScrolling = new Subject();
|
|
1184
|
+
this._selectedIndex = 0;
|
|
1185
|
+
/**
|
|
1186
|
+
* Event emitted when the option is selected.
|
|
1187
|
+
*/
|
|
1188
|
+
this.selectFocusedIndex = new EventEmitter();
|
|
1189
|
+
/**
|
|
1190
|
+
* Event emitted when a label is focused.
|
|
1191
|
+
*/
|
|
1192
|
+
this.indexFocused = new EventEmitter();
|
|
1193
|
+
// Bind the `mouseleave` event on the outside since it doesn't change anything in the view.
|
|
1194
|
+
_ngZone.runOutsideAngular((/**
|
|
1195
|
+
* @return {?}
|
|
1196
|
+
*/
|
|
1197
|
+
() => {
|
|
1198
|
+
fromEvent(_elementRef.nativeElement, 'mouseleave')
|
|
1199
|
+
.pipe(takeUntil(this._destroyed))
|
|
1200
|
+
.subscribe((/**
|
|
1201
|
+
* @return {?}
|
|
1202
|
+
*/
|
|
1203
|
+
() => {
|
|
1204
|
+
this._stopInterval();
|
|
1205
|
+
}));
|
|
1206
|
+
}));
|
|
1145
1207
|
}
|
|
1146
1208
|
/**
|
|
1147
|
-
*
|
|
1209
|
+
* The index of the active tab.
|
|
1148
1210
|
* @return {?}
|
|
1149
1211
|
*/
|
|
1150
|
-
|
|
1151
|
-
/** @type {?} */
|
|
1152
|
-
const selectedItem = this._items && this._items.length ?
|
|
1153
|
-
this._items.toArray()[this.selectedIndex] : null;
|
|
1154
|
-
/** @type {?} */
|
|
1155
|
-
const selectedLabelWrapper = selectedItem ? selectedItem.elementRef.nativeElement : null;
|
|
1156
|
-
if (selectedLabelWrapper) {
|
|
1157
|
-
this._inkBar.alignToElement(selectedLabelWrapper);
|
|
1158
|
-
}
|
|
1159
|
-
else {
|
|
1160
|
-
this._inkBar.hide();
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1212
|
+
get selectedIndex() { return this._selectedIndex; }
|
|
1163
1213
|
/**
|
|
1164
|
-
*
|
|
1214
|
+
* @param {?} value
|
|
1165
1215
|
* @return {?}
|
|
1166
1216
|
*/
|
|
1167
|
-
|
|
1168
|
-
|
|
1217
|
+
set selectedIndex(value) {
|
|
1218
|
+
value = coerceNumberProperty(value);
|
|
1219
|
+
if (this._selectedIndex != value) {
|
|
1220
|
+
this._selectedIndexChanged = true;
|
|
1221
|
+
this._selectedIndex = value;
|
|
1222
|
+
if (this._keyManager) {
|
|
1223
|
+
this._keyManager.updateActiveItemIndex(value);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1169
1226
|
}
|
|
1170
1227
|
/**
|
|
1171
|
-
* Handles the user pressing down on one of the paginators.
|
|
1172
|
-
* Starts scrolling the header after a certain amount of time.
|
|
1173
|
-
* @param {?} direction In which direction the paginator should be scrolled.
|
|
1174
1228
|
* @return {?}
|
|
1175
1229
|
*/
|
|
1176
|
-
|
|
1177
|
-
//
|
|
1178
|
-
this.
|
|
1179
|
-
|
|
1180
|
-
timer(HEADER_SCROLL_DELAY, HEADER_SCROLL_INTERVAL)
|
|
1181
|
-
// Keep the timer going until something tells it to stop or the component is destroyed.
|
|
1182
|
-
.pipe(takeUntil(merge(this._stopScrolling, this._destroyed)))
|
|
1230
|
+
ngAfterViewInit() {
|
|
1231
|
+
// We need to handle these events manually, because we want to bind passive event listeners.
|
|
1232
|
+
fromEvent(this._previousPaginator.nativeElement, 'touchstart', passiveEventListenerOptions)
|
|
1233
|
+
.pipe(takeUntil(this._destroyed))
|
|
1183
1234
|
.subscribe((/**
|
|
1184
1235
|
* @return {?}
|
|
1185
1236
|
*/
|
|
1186
1237
|
() => {
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1238
|
+
this._handlePaginatorPress('before');
|
|
1239
|
+
}));
|
|
1240
|
+
fromEvent(this._nextPaginator.nativeElement, 'touchstart', passiveEventListenerOptions)
|
|
1241
|
+
.pipe(takeUntil(this._destroyed))
|
|
1242
|
+
.subscribe((/**
|
|
1243
|
+
* @return {?}
|
|
1244
|
+
*/
|
|
1245
|
+
() => {
|
|
1246
|
+
this._handlePaginatorPress('after');
|
|
1192
1247
|
}));
|
|
1193
1248
|
}
|
|
1194
1249
|
/**
|
|
1195
|
-
*
|
|
1196
|
-
* @private
|
|
1197
|
-
* @param {?} position Position to which to scroll.
|
|
1198
|
-
* @return {?} Information on the current scroll distance and the maximum.
|
|
1250
|
+
* @return {?}
|
|
1199
1251
|
*/
|
|
1200
|
-
|
|
1252
|
+
ngAfterContentInit() {
|
|
1201
1253
|
/** @type {?} */
|
|
1202
|
-
const
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1254
|
+
const dirChange = this._dir ? this._dir.change : of(null);
|
|
1255
|
+
/** @type {?} */
|
|
1256
|
+
const resize = this._viewportRuler.change(150);
|
|
1257
|
+
/** @type {?} */
|
|
1258
|
+
const realign = (/**
|
|
1259
|
+
* @return {?}
|
|
1260
|
+
*/
|
|
1261
|
+
() => {
|
|
1262
|
+
this.updatePagination();
|
|
1263
|
+
this._alignInkBarToSelectedTab();
|
|
1264
|
+
});
|
|
1265
|
+
this._keyManager = new FocusKeyManager(this._items)
|
|
1266
|
+
.withHorizontalOrientation(this._getLayoutDirection())
|
|
1267
|
+
.withWrap();
|
|
1268
|
+
this._keyManager.updateActiveItem(0);
|
|
1269
|
+
// Defer the first call in order to allow for slower browsers to lay out the elements.
|
|
1270
|
+
// This helps in cases where the user lands directly on a page with paginated tabs.
|
|
1271
|
+
typeof requestAnimationFrame !== 'undefined' ? requestAnimationFrame(realign) : realign();
|
|
1272
|
+
// On dir change or window resize, realign the ink bar and update the orientation of
|
|
1273
|
+
// the key manager if the direction has changed.
|
|
1274
|
+
merge(dirChange, resize, this._items.changes).pipe(takeUntil(this._destroyed)).subscribe((/**
|
|
1275
|
+
* @return {?}
|
|
1276
|
+
*/
|
|
1277
|
+
() => {
|
|
1278
|
+
realign();
|
|
1279
|
+
this._keyManager.withHorizontalOrientation(this._getLayoutDirection());
|
|
1280
|
+
}));
|
|
1281
|
+
// If there is a change in the focus key manager we need to emit the `indexFocused`
|
|
1282
|
+
// event in order to provide a public event that notifies about focus changes. Also we realign
|
|
1283
|
+
// the tabs container by scrolling the new focused tab into the visible section.
|
|
1284
|
+
this._keyManager.change.pipe(takeUntil(this._destroyed)).subscribe((/**
|
|
1285
|
+
* @param {?} newFocusIndex
|
|
1286
|
+
* @return {?}
|
|
1287
|
+
*/
|
|
1288
|
+
newFocusIndex => {
|
|
1289
|
+
this.indexFocused.emit(newFocusIndex);
|
|
1290
|
+
this._setTabFocus(newFocusIndex);
|
|
1291
|
+
}));
|
|
1209
1292
|
}
|
|
1210
|
-
}
|
|
1211
|
-
/** @nocollapse */
|
|
1212
|
-
MatPaginatedTabHeader.ctorParameters = () => [
|
|
1213
|
-
{ type: ElementRef },
|
|
1214
|
-
{ type: ChangeDetectorRef },
|
|
1215
|
-
{ type: ViewportRuler },
|
|
1216
|
-
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
1217
|
-
{ type: NgZone },
|
|
1218
|
-
{ type: Platform },
|
|
1219
|
-
{ type: String }
|
|
1220
|
-
];
|
|
1221
|
-
|
|
1222
|
-
/**
|
|
1223
|
-
* @fileoverview added by tsickle
|
|
1224
|
-
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1225
|
-
*/
|
|
1226
|
-
/**
|
|
1227
|
-
* The header of the tab group which displays a list of all the tabs in the tab group. Includes
|
|
1228
|
-
* an ink bar that follows the currently selected tab. When the tabs list's width exceeds the
|
|
1229
|
-
* width of the header container, then arrows will be displayed to allow the user to scroll
|
|
1230
|
-
* left and right across the header.
|
|
1231
|
-
* \@docs-private
|
|
1232
|
-
*/
|
|
1233
|
-
class MatTabHeader extends MatPaginatedTabHeader {
|
|
1234
1293
|
/**
|
|
1235
|
-
* @
|
|
1236
|
-
* @param {?} changeDetectorRef
|
|
1237
|
-
* @param {?} viewportRuler
|
|
1238
|
-
* @param {?} dir
|
|
1239
|
-
* @param {?} ngZone
|
|
1240
|
-
* @param {?} platform
|
|
1241
|
-
* @param {?=} animationMode
|
|
1294
|
+
* @return {?}
|
|
1242
1295
|
*/
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1296
|
+
ngAfterContentChecked() {
|
|
1297
|
+
// If the number of tab labels have changed, check if scrolling should be enabled
|
|
1298
|
+
if (this._tabLabelCount != this._items.length) {
|
|
1299
|
+
this.updatePagination();
|
|
1300
|
+
this._tabLabelCount = this._items.length;
|
|
1301
|
+
this._changeDetectorRef.markForCheck();
|
|
1302
|
+
}
|
|
1303
|
+
// If the selected index has changed, scroll to the label and check if the scrolling controls
|
|
1304
|
+
// should be disabled.
|
|
1305
|
+
if (this._selectedIndexChanged) {
|
|
1306
|
+
this._scrollToLabel(this._selectedIndex);
|
|
1307
|
+
this._checkScrollingControls();
|
|
1308
|
+
this._alignInkBarToSelectedTab();
|
|
1309
|
+
this._selectedIndexChanged = false;
|
|
1310
|
+
this._changeDetectorRef.markForCheck();
|
|
1311
|
+
}
|
|
1312
|
+
// If the scroll distance has been changed (tab selected, focused, scroll controls activated),
|
|
1313
|
+
// then translate the header to reflect this.
|
|
1314
|
+
if (this._scrollDistanceChanged) {
|
|
1315
|
+
this._updateTabScrollPosition();
|
|
1316
|
+
this._scrollDistanceChanged = false;
|
|
1317
|
+
this._changeDetectorRef.markForCheck();
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
/**
|
|
1321
|
+
* @return {?}
|
|
1322
|
+
*/
|
|
1323
|
+
ngOnDestroy() {
|
|
1324
|
+
this._destroyed.next();
|
|
1325
|
+
this._destroyed.complete();
|
|
1326
|
+
this._stopScrolling.complete();
|
|
1327
|
+
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Handles keyboard events on the header.
|
|
1330
|
+
* @param {?} event
|
|
1331
|
+
* @return {?}
|
|
1332
|
+
*/
|
|
1333
|
+
_handleKeydown(event) {
|
|
1334
|
+
// We don't handle any key bindings with a modifier key.
|
|
1335
|
+
if (hasModifierKey(event)) {
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
switch (event.keyCode) {
|
|
1339
|
+
case HOME:
|
|
1340
|
+
this._keyManager.setFirstItemActive();
|
|
1341
|
+
event.preventDefault();
|
|
1342
|
+
break;
|
|
1343
|
+
case END:
|
|
1344
|
+
this._keyManager.setLastItemActive();
|
|
1345
|
+
event.preventDefault();
|
|
1346
|
+
break;
|
|
1347
|
+
case ENTER:
|
|
1348
|
+
case SPACE:
|
|
1349
|
+
this.selectFocusedIndex.emit(this.focusIndex);
|
|
1350
|
+
this._itemSelected(event);
|
|
1351
|
+
break;
|
|
1352
|
+
default:
|
|
1353
|
+
this._keyManager.onKeydown(event);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Callback for when the MutationObserver detects that the content has changed.
|
|
1358
|
+
* @return {?}
|
|
1359
|
+
*/
|
|
1360
|
+
_onContentChanges() {
|
|
1361
|
+
/** @type {?} */
|
|
1362
|
+
const textContent = this._elementRef.nativeElement.textContent;
|
|
1363
|
+
// We need to diff the text content of the header, because the MutationObserver callback
|
|
1364
|
+
// will fire even if the text content didn't change which is inefficient and is prone
|
|
1365
|
+
// to infinite loops if a poorly constructed expression is passed in (see #14249).
|
|
1366
|
+
if (textContent !== this._currentTextContent) {
|
|
1367
|
+
this._currentTextContent = textContent || '';
|
|
1368
|
+
// The content observer runs outside the `NgZone` by default, which
|
|
1369
|
+
// means that we need to bring the callback back in ourselves.
|
|
1370
|
+
this._ngZone.run((/**
|
|
1371
|
+
* @return {?}
|
|
1372
|
+
*/
|
|
1373
|
+
() => {
|
|
1374
|
+
this.updatePagination();
|
|
1375
|
+
this._alignInkBarToSelectedTab();
|
|
1376
|
+
this._changeDetectorRef.markForCheck();
|
|
1377
|
+
}));
|
|
1378
|
+
}
|
|
1248
1379
|
}
|
|
1249
1380
|
/**
|
|
1250
|
-
*
|
|
1251
|
-
*
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
* @param {?} value
|
|
1256
|
-
* @return {?}
|
|
1257
|
-
*/
|
|
1258
|
-
set disableRipple(value) { this._disableRipple = coerceBooleanProperty(value); }
|
|
1259
|
-
/**
|
|
1260
|
-
* @protected
|
|
1261
|
-
* @param {?} event
|
|
1381
|
+
* Updates the view whether pagination should be enabled or not.
|
|
1382
|
+
*
|
|
1383
|
+
* WARNING: Calling this method can be very costly in terms of performance. It should be called
|
|
1384
|
+
* as infrequently as possible from outside of the Tabs component as it causes a reflow of the
|
|
1385
|
+
* page.
|
|
1262
1386
|
* @return {?}
|
|
1263
1387
|
*/
|
|
1264
|
-
|
|
1265
|
-
|
|
1388
|
+
updatePagination() {
|
|
1389
|
+
this._checkPaginationEnabled();
|
|
1390
|
+
this._checkScrollingControls();
|
|
1391
|
+
this._updateTabScrollPosition();
|
|
1266
1392
|
}
|
|
1267
|
-
}
|
|
1268
|
-
MatTabHeader.decorators = [
|
|
1269
|
-
{ type: Component, args: [{selector: 'mat-tab-header',
|
|
1270
|
-
template: "<div class=\"mat-tab-header-pagination mat-tab-header-pagination-before mat-elevation-z4\" #previousPaginator aria-hidden=\"true\" mat-ripple [matRippleDisabled]=\"_disableScrollBefore || disableRipple\" [class.mat-tab-header-pagination-disabled]=\"_disableScrollBefore\" (click)=\"_handlePaginatorClick('before')\" (mousedown)=\"_handlePaginatorPress('before')\" (touchend)=\"_stopInterval()\"><div class=\"mat-tab-header-pagination-chevron\"></div></div><div class=\"mat-tab-label-container\" #tabListContainer (keydown)=\"_handleKeydown($event)\"><div #tabList class=\"mat-tab-list\" [class._mat-animation-noopable]=\"_animationMode === 'NoopAnimations'\" role=\"tablist\" (cdkObserveContent)=\"_onContentChanges()\"><div class=\"mat-tab-labels\"><ng-content></ng-content></div><mat-ink-bar></mat-ink-bar></div></div><div class=\"mat-tab-header-pagination mat-tab-header-pagination-after mat-elevation-z4\" #nextPaginator aria-hidden=\"true\" mat-ripple [matRippleDisabled]=\"_disableScrollAfter || disableRipple\" [class.mat-tab-header-pagination-disabled]=\"_disableScrollAfter\" (mousedown)=\"_handlePaginatorPress('after')\" (click)=\"_handlePaginatorClick('after')\" (touchend)=\"_stopInterval()\"><div class=\"mat-tab-header-pagination-chevron\"></div></div>",
|
|
1271
|
-
styles: [".mat-tab-header{display:flex;overflow:hidden;position:relative;flex-shrink:0}.mat-tab-header-pagination{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:none;justify-content:center;align-items:center;min-width:32px;cursor:pointer;z-index:2;-webkit-tap-highlight-color:transparent;touch-action:none}.mat-tab-header-pagination-controls-enabled .mat-tab-header-pagination{display:flex}.mat-tab-header-pagination-before,.mat-tab-header-rtl .mat-tab-header-pagination-after{padding-left:4px}.mat-tab-header-pagination-before .mat-tab-header-pagination-chevron,.mat-tab-header-rtl .mat-tab-header-pagination-after .mat-tab-header-pagination-chevron{transform:rotate(-135deg)}.mat-tab-header-pagination-after,.mat-tab-header-rtl .mat-tab-header-pagination-before{padding-right:4px}.mat-tab-header-pagination-after .mat-tab-header-pagination-chevron,.mat-tab-header-rtl .mat-tab-header-pagination-before .mat-tab-header-pagination-chevron{transform:rotate(45deg)}.mat-tab-header-pagination-chevron{border-style:solid;border-width:2px 2px 0 0;content:'';height:8px;width:8px}.mat-tab-header-pagination-disabled{box-shadow:none;cursor:default}.mat-tab-list{flex-grow:1;position:relative;transition:transform .5s cubic-bezier(.35,0,.25,1)}.mat-ink-bar{position:absolute;bottom:0;height:2px;transition:.5s cubic-bezier(.35,0,.25,1)}._mat-animation-noopable.mat-ink-bar{transition:none;animation:none}.mat-tab-group-inverted-header .mat-ink-bar{bottom:auto;top:0}@media (-ms-high-contrast:active){.mat-ink-bar{outline:solid 2px;height:0}}.mat-tab-labels{display:flex}[mat-align-tabs=center] .mat-tab-labels{justify-content:center}[mat-align-tabs=end] .mat-tab-labels{justify-content:flex-end}.mat-tab-label-container{display:flex;flex-grow:1;overflow:hidden;z-index:1}._mat-animation-noopable.mat-tab-list{transition:none;animation:none}.mat-tab-label{height:48px;padding:0 24px;cursor:pointer;box-sizing:border-box;opacity:.6;min-width:160px;text-align:center;display:inline-flex;justify-content:center;align-items:center;white-space:nowrap;position:relative}.mat-tab-label:focus{outline:0}.mat-tab-label:focus:not(.mat-tab-disabled){opacity:1}@media (-ms-high-contrast:active){.mat-tab-label:focus{outline:dotted 2px}}.mat-tab-label.mat-tab-disabled{cursor:default}@media (-ms-high-contrast:active){.mat-tab-label.mat-tab-disabled{opacity:.5}}.mat-tab-label .mat-tab-label-content{display:inline-flex;justify-content:center;align-items:center;white-space:nowrap}@media (-ms-high-contrast:active){.mat-tab-label{opacity:1}}@media (max-width:599px){.mat-tab-label{min-width:72px}}"],
|
|
1272
|
-
inputs: ['selectedIndex'],
|
|
1273
|
-
outputs: ['selectFocusedIndex', 'indexFocused'],
|
|
1274
|
-
encapsulation: ViewEncapsulation.None,
|
|
1275
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1276
|
-
host: {
|
|
1277
|
-
'class': 'mat-tab-header',
|
|
1278
|
-
'[class.mat-tab-header-pagination-controls-enabled]': '_showPaginationControls',
|
|
1279
|
-
'[class.mat-tab-header-rtl]': "_getLayoutDirection() == 'rtl'",
|
|
1280
|
-
},
|
|
1281
|
-
},] },
|
|
1282
|
-
];
|
|
1283
|
-
/** @nocollapse */
|
|
1284
|
-
MatTabHeader.ctorParameters = () => [
|
|
1285
|
-
{ type: ElementRef },
|
|
1286
|
-
{ type: ChangeDetectorRef },
|
|
1287
|
-
{ type: ViewportRuler },
|
|
1288
|
-
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
1289
|
-
{ type: NgZone },
|
|
1290
|
-
{ type: Platform },
|
|
1291
|
-
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
|
|
1292
|
-
];
|
|
1293
|
-
MatTabHeader.propDecorators = {
|
|
1294
|
-
_items: [{ type: ContentChildren, args: [MatTabLabelWrapper,] }],
|
|
1295
|
-
_inkBar: [{ type: ViewChild, args: [MatInkBar, { static: true },] }],
|
|
1296
|
-
_tabListContainer: [{ type: ViewChild, args: ['tabListContainer', { static: true },] }],
|
|
1297
|
-
_tabList: [{ type: ViewChild, args: ['tabList', { static: true },] }],
|
|
1298
|
-
_nextPaginator: [{ type: ViewChild, args: ['nextPaginator', { static: false },] }],
|
|
1299
|
-
_previousPaginator: [{ type: ViewChild, args: ['previousPaginator', { static: false },] }],
|
|
1300
|
-
disableRipple: [{ type: Input }]
|
|
1301
|
-
};
|
|
1302
|
-
|
|
1303
|
-
/**
|
|
1304
|
-
* @fileoverview added by tsickle
|
|
1305
|
-
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1306
|
-
*/
|
|
1307
|
-
/**
|
|
1308
|
-
* Used to generate unique ID's for each tab component
|
|
1309
|
-
* @type {?}
|
|
1310
|
-
*/
|
|
1311
|
-
let nextId = 0;
|
|
1312
|
-
/**
|
|
1313
|
-
* A simple change event emitted on focus or selection changes.
|
|
1314
|
-
*/
|
|
1315
|
-
class MatTabChangeEvent {
|
|
1316
|
-
}
|
|
1317
|
-
/**
|
|
1318
|
-
* Injection token that can be used to provide the default options the tabs module.
|
|
1319
|
-
* @type {?}
|
|
1320
|
-
*/
|
|
1321
|
-
const MAT_TABS_CONFIG = new InjectionToken('MAT_TABS_CONFIG');
|
|
1322
|
-
// Boilerplate for applying mixins to MatTabGroup.
|
|
1323
|
-
/**
|
|
1324
|
-
* \@docs-private
|
|
1325
|
-
*/
|
|
1326
|
-
class MatTabGroupBase {
|
|
1327
1393
|
/**
|
|
1328
|
-
*
|
|
1394
|
+
* Tracks which element has focus; used for keyboard navigation
|
|
1395
|
+
* @return {?}
|
|
1329
1396
|
*/
|
|
1330
|
-
|
|
1331
|
-
this.
|
|
1397
|
+
get focusIndex() {
|
|
1398
|
+
return this._keyManager ? (/** @type {?} */ (this._keyManager.activeItemIndex)) : 0;
|
|
1332
1399
|
}
|
|
1333
|
-
}
|
|
1334
|
-
/** @type {?} */
|
|
1335
|
-
const _MatTabGroupMixinBase = mixinColor(mixinDisableRipple(MatTabGroupBase), 'primary');
|
|
1336
|
-
/**
|
|
1337
|
-
* Material design tab-group component. Supports basic tab pairs (label + content) and includes
|
|
1338
|
-
* animated ink-bar, keyboard navigation, and screen reader.
|
|
1339
|
-
* See: https://material.io/design/components/tabs.html
|
|
1340
|
-
*/
|
|
1341
|
-
class MatTabGroup extends _MatTabGroupMixinBase {
|
|
1342
1400
|
/**
|
|
1343
|
-
*
|
|
1344
|
-
* @param {?}
|
|
1345
|
-
* @
|
|
1346
|
-
* @param {?=} _animationMode
|
|
1401
|
+
* When the focus index is set, we must manually send focus to the correct label
|
|
1402
|
+
* @param {?} value
|
|
1403
|
+
* @return {?}
|
|
1347
1404
|
*/
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
* The tab index that should be selected after the content has been checked.
|
|
1354
|
-
*/
|
|
1355
|
-
this._indexToSelect = 0;
|
|
1356
|
-
/**
|
|
1357
|
-
* Snapshot of the height of the tab body wrapper before another tab is activated.
|
|
1358
|
-
*/
|
|
1359
|
-
this._tabBodyWrapperHeight = 0;
|
|
1360
|
-
/**
|
|
1361
|
-
* Subscription to tabs being added/removed.
|
|
1362
|
-
*/
|
|
1363
|
-
this._tabsSubscription = Subscription.EMPTY;
|
|
1364
|
-
/**
|
|
1365
|
-
* Subscription to changes in the tab labels.
|
|
1366
|
-
*/
|
|
1367
|
-
this._tabLabelSubscription = Subscription.EMPTY;
|
|
1368
|
-
this._dynamicHeight = false;
|
|
1369
|
-
this._selectedIndex = null;
|
|
1370
|
-
/**
|
|
1371
|
-
* Position of the tab header.
|
|
1372
|
-
*/
|
|
1373
|
-
this.headerPosition = 'above';
|
|
1374
|
-
/**
|
|
1375
|
-
* Output to enable support for two-way binding on `[(selectedIndex)]`
|
|
1376
|
-
*/
|
|
1377
|
-
this.selectedIndexChange = new EventEmitter();
|
|
1378
|
-
/**
|
|
1379
|
-
* Event emitted when focus has changed within a tab group.
|
|
1380
|
-
*/
|
|
1381
|
-
this.focusChange = new EventEmitter();
|
|
1382
|
-
/**
|
|
1383
|
-
* Event emitted when the body animation has completed
|
|
1384
|
-
*/
|
|
1385
|
-
this.animationDone = new EventEmitter();
|
|
1386
|
-
/**
|
|
1387
|
-
* Event emitted when the tab selection has changed.
|
|
1388
|
-
*/
|
|
1389
|
-
this.selectedTabChange = new EventEmitter(true);
|
|
1390
|
-
this._groupId = nextId++;
|
|
1391
|
-
this.animationDuration = defaultConfig && defaultConfig.animationDuration ?
|
|
1392
|
-
defaultConfig.animationDuration : '500ms';
|
|
1405
|
+
set focusIndex(value) {
|
|
1406
|
+
if (!this._isValidIndex(value) || this.focusIndex === value || !this._keyManager) {
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
this._keyManager.setActiveItem(value);
|
|
1393
1410
|
}
|
|
1394
1411
|
/**
|
|
1395
|
-
*
|
|
1412
|
+
* Determines if an index is valid. If the tabs are not ready yet, we assume that the user is
|
|
1413
|
+
* providing a valid index and return true.
|
|
1414
|
+
* @param {?} index
|
|
1396
1415
|
* @return {?}
|
|
1397
1416
|
*/
|
|
1398
|
-
|
|
1417
|
+
_isValidIndex(index) {
|
|
1418
|
+
if (!this._items) {
|
|
1419
|
+
return true;
|
|
1420
|
+
}
|
|
1421
|
+
/** @type {?} */
|
|
1422
|
+
const tab = this._items ? this._items.toArray()[index] : null;
|
|
1423
|
+
return !!tab && !tab.disabled;
|
|
1424
|
+
}
|
|
1399
1425
|
/**
|
|
1400
|
-
*
|
|
1426
|
+
* Sets focus on the HTML element for the label wrapper and scrolls it into the view if
|
|
1427
|
+
* scrolling is enabled.
|
|
1428
|
+
* @param {?} tabIndex
|
|
1401
1429
|
* @return {?}
|
|
1402
1430
|
*/
|
|
1403
|
-
|
|
1431
|
+
_setTabFocus(tabIndex) {
|
|
1432
|
+
if (this._showPaginationControls) {
|
|
1433
|
+
this._scrollToLabel(tabIndex);
|
|
1434
|
+
}
|
|
1435
|
+
if (this._items && this._items.length) {
|
|
1436
|
+
this._items.toArray()[tabIndex].focus();
|
|
1437
|
+
// Do not let the browser manage scrolling to focus the element, this will be handled
|
|
1438
|
+
// by using translation. In LTR, the scroll left should be 0. In RTL, the scroll width
|
|
1439
|
+
// should be the full width minus the offset width.
|
|
1440
|
+
/** @type {?} */
|
|
1441
|
+
const containerEl = this._tabListContainer.nativeElement;
|
|
1442
|
+
/** @type {?} */
|
|
1443
|
+
const dir = this._getLayoutDirection();
|
|
1444
|
+
if (dir == 'ltr') {
|
|
1445
|
+
containerEl.scrollLeft = 0;
|
|
1446
|
+
}
|
|
1447
|
+
else {
|
|
1448
|
+
containerEl.scrollLeft = containerEl.scrollWidth - containerEl.offsetWidth;
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1404
1452
|
/**
|
|
1405
|
-
* The
|
|
1453
|
+
* The layout direction of the containing app.
|
|
1406
1454
|
* @return {?}
|
|
1407
1455
|
*/
|
|
1408
|
-
|
|
1456
|
+
_getLayoutDirection() {
|
|
1457
|
+
return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
|
|
1458
|
+
}
|
|
1409
1459
|
/**
|
|
1410
|
-
*
|
|
1460
|
+
* Performs the CSS transformation on the tab list that will cause the list to scroll.
|
|
1411
1461
|
* @return {?}
|
|
1412
1462
|
*/
|
|
1413
|
-
|
|
1414
|
-
|
|
1463
|
+
_updateTabScrollPosition() {
|
|
1464
|
+
/** @type {?} */
|
|
1465
|
+
const scrollDistance = this.scrollDistance;
|
|
1466
|
+
/** @type {?} */
|
|
1467
|
+
const platform = this._platform;
|
|
1468
|
+
/** @type {?} */
|
|
1469
|
+
const translateX = this._getLayoutDirection() === 'ltr' ? -scrollDistance : scrollDistance;
|
|
1470
|
+
// Don't use `translate3d` here because we don't want to create a new layer. A new layer
|
|
1471
|
+
// seems to cause flickering and overflow in Internet Explorer. For example, the ink bar
|
|
1472
|
+
// and ripples will exceed the boundaries of the visible tab bar.
|
|
1473
|
+
// See: https://github.com/angular/components/issues/10276
|
|
1474
|
+
// We round the `transform` here, because transforms with sub-pixel precision cause some
|
|
1475
|
+
// browsers to blur the content of the element.
|
|
1476
|
+
this._tabList.nativeElement.style.transform = `translateX(${Math.round(translateX)}px)`;
|
|
1477
|
+
// Setting the `transform` on IE will change the scroll offset of the parent, causing the
|
|
1478
|
+
// position to be thrown off in some cases. We have to reset it ourselves to ensure that
|
|
1479
|
+
// it doesn't get thrown off. Note that we scope it only to IE and Edge, because messing
|
|
1480
|
+
// with the scroll position throws off Chrome 71+ in RTL mode (see #14689).
|
|
1481
|
+
// @breaking-change 9.0.0 Remove null check for `platform` after it can no longer be undefined.
|
|
1482
|
+
if (platform && (platform.TRIDENT || platform.EDGE)) {
|
|
1483
|
+
this._tabListContainer.nativeElement.scrollLeft = 0;
|
|
1484
|
+
}
|
|
1415
1485
|
}
|
|
1416
1486
|
/**
|
|
1417
|
-
*
|
|
1487
|
+
* Sets the distance in pixels that the tab header should be transformed in the X-axis.
|
|
1418
1488
|
* @return {?}
|
|
1419
1489
|
*/
|
|
1420
|
-
get
|
|
1490
|
+
get scrollDistance() { return this._scrollDistance; }
|
|
1421
1491
|
/**
|
|
1422
1492
|
* @param {?} value
|
|
1423
1493
|
* @return {?}
|
|
1424
1494
|
*/
|
|
1425
|
-
set
|
|
1426
|
-
this.
|
|
1495
|
+
set scrollDistance(value) {
|
|
1496
|
+
this._scrollTo(value);
|
|
1427
1497
|
}
|
|
1428
1498
|
/**
|
|
1429
|
-
*
|
|
1499
|
+
* Moves the tab list in the 'before' or 'after' direction (towards the beginning of the list or
|
|
1500
|
+
* the end of the list, respectively). The distance to scroll is computed to be a third of the
|
|
1501
|
+
* length of the tab list view window.
|
|
1502
|
+
*
|
|
1503
|
+
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
1504
|
+
* should be called sparingly.
|
|
1505
|
+
* @param {?} direction
|
|
1430
1506
|
* @return {?}
|
|
1431
1507
|
*/
|
|
1432
|
-
|
|
1508
|
+
_scrollHeader(direction) {
|
|
1509
|
+
/** @type {?} */
|
|
1510
|
+
const viewLength = this._tabListContainer.nativeElement.offsetWidth;
|
|
1511
|
+
// Move the scroll distance one-third the length of the tab list's viewport.
|
|
1512
|
+
/** @type {?} */
|
|
1513
|
+
const scrollAmount = (direction == 'before' ? -1 : 1) * viewLength / 3;
|
|
1514
|
+
return this._scrollTo(this._scrollDistance + scrollAmount);
|
|
1515
|
+
}
|
|
1433
1516
|
/**
|
|
1434
|
-
*
|
|
1517
|
+
* Handles click events on the pagination arrows.
|
|
1518
|
+
* @param {?} direction
|
|
1435
1519
|
* @return {?}
|
|
1436
1520
|
*/
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
nativeElement.classList.remove(`mat-background-${this.backgroundColor}`);
|
|
1441
|
-
if (value) {
|
|
1442
|
-
nativeElement.classList.add(`mat-background-${value}`);
|
|
1443
|
-
}
|
|
1444
|
-
this._backgroundColor = value;
|
|
1521
|
+
_handlePaginatorClick(direction) {
|
|
1522
|
+
this._stopInterval();
|
|
1523
|
+
this._scrollHeader(direction);
|
|
1445
1524
|
}
|
|
1446
1525
|
/**
|
|
1447
|
-
*
|
|
1448
|
-
*
|
|
1449
|
-
*
|
|
1450
|
-
*
|
|
1526
|
+
* Moves the tab list such that the desired tab label (marked by index) is moved into view.
|
|
1527
|
+
*
|
|
1528
|
+
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
1529
|
+
* should be called sparingly.
|
|
1530
|
+
* @param {?} labelIndex
|
|
1451
1531
|
* @return {?}
|
|
1452
1532
|
*/
|
|
1453
|
-
|
|
1454
|
-
// Don't clamp the `indexToSelect` immediately in the setter because it can happen that
|
|
1455
|
-
// the amount of tabs changes before the actual change detection runs.
|
|
1533
|
+
_scrollToLabel(labelIndex) {
|
|
1456
1534
|
/** @type {?} */
|
|
1457
|
-
const
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
if (this._selectedIndex != indexToSelect) {
|
|
1461
|
-
/** @type {?} */
|
|
1462
|
-
const isFirstRun = this._selectedIndex == null;
|
|
1463
|
-
if (!isFirstRun) {
|
|
1464
|
-
this.selectedTabChange.emit(this._createChangeEvent(indexToSelect));
|
|
1465
|
-
}
|
|
1466
|
-
// Changing these values after change detection has run
|
|
1467
|
-
// since the checked content may contain references to them.
|
|
1468
|
-
Promise.resolve().then((/**
|
|
1469
|
-
* @return {?}
|
|
1470
|
-
*/
|
|
1471
|
-
() => {
|
|
1472
|
-
this._tabs.forEach((/**
|
|
1473
|
-
* @param {?} tab
|
|
1474
|
-
* @param {?} index
|
|
1475
|
-
* @return {?}
|
|
1476
|
-
*/
|
|
1477
|
-
(tab, index) => tab.isActive = index === indexToSelect));
|
|
1478
|
-
if (!isFirstRun) {
|
|
1479
|
-
this.selectedIndexChange.emit(indexToSelect);
|
|
1480
|
-
}
|
|
1481
|
-
}));
|
|
1535
|
+
const selectedLabel = this._items ? this._items.toArray()[labelIndex] : null;
|
|
1536
|
+
if (!selectedLabel) {
|
|
1537
|
+
return;
|
|
1482
1538
|
}
|
|
1483
|
-
//
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1539
|
+
// The view length is the visible width of the tab labels.
|
|
1540
|
+
/** @type {?} */
|
|
1541
|
+
const viewLength = this._tabListContainer.nativeElement.offsetWidth;
|
|
1542
|
+
const { offsetLeft, offsetWidth } = selectedLabel.elementRef.nativeElement;
|
|
1543
|
+
/** @type {?} */
|
|
1544
|
+
let labelBeforePos;
|
|
1545
|
+
/** @type {?} */
|
|
1546
|
+
let labelAfterPos;
|
|
1547
|
+
if (this._getLayoutDirection() == 'ltr') {
|
|
1548
|
+
labelBeforePos = offsetLeft;
|
|
1549
|
+
labelAfterPos = labelBeforePos + offsetWidth;
|
|
1550
|
+
}
|
|
1551
|
+
else {
|
|
1552
|
+
labelAfterPos = this._tabList.nativeElement.offsetWidth - offsetLeft;
|
|
1553
|
+
labelBeforePos = labelAfterPos - offsetWidth;
|
|
1554
|
+
}
|
|
1555
|
+
/** @type {?} */
|
|
1556
|
+
const beforeVisiblePos = this.scrollDistance;
|
|
1557
|
+
/** @type {?} */
|
|
1558
|
+
const afterVisiblePos = this.scrollDistance + viewLength;
|
|
1559
|
+
if (labelBeforePos < beforeVisiblePos) {
|
|
1560
|
+
// Scroll header to move label to the before direction
|
|
1561
|
+
this.scrollDistance -= beforeVisiblePos - labelBeforePos + EXAGGERATED_OVERSCROLL;
|
|
1562
|
+
}
|
|
1563
|
+
else if (labelAfterPos > afterVisiblePos) {
|
|
1564
|
+
// Scroll header to move label to the after direction
|
|
1565
|
+
this.scrollDistance += labelAfterPos - afterVisiblePos + EXAGGERATED_OVERSCROLL;
|
|
1500
1566
|
}
|
|
1501
1567
|
}
|
|
1502
1568
|
/**
|
|
1569
|
+
* Evaluate whether the pagination controls should be displayed. If the scroll width of the
|
|
1570
|
+
* tab list is wider than the size of the header container, then the pagination controls should
|
|
1571
|
+
* be shown.
|
|
1572
|
+
*
|
|
1573
|
+
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
1574
|
+
* should be called sparingly.
|
|
1503
1575
|
* @return {?}
|
|
1504
1576
|
*/
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
() => {
|
|
1513
|
-
/** @type {?} */
|
|
1514
|
-
const indexToSelect = this._clampTabIndex(this._indexToSelect);
|
|
1515
|
-
// Maintain the previously-selected tab if a new tab is added or removed and there is no
|
|
1516
|
-
// explicit change that selects a different tab.
|
|
1517
|
-
if (indexToSelect === this._selectedIndex) {
|
|
1518
|
-
/** @type {?} */
|
|
1519
|
-
const tabs = this._tabs.toArray();
|
|
1520
|
-
for (let i = 0; i < tabs.length; i++) {
|
|
1521
|
-
if (tabs[i].isActive) {
|
|
1522
|
-
// Assign both to the `_indexToSelect` and `_selectedIndex` so we don't fire a changed
|
|
1523
|
-
// event, otherwise the consumer may end up in an infinite loop in some edge cases like
|
|
1524
|
-
// adding a tab within the `selectedIndexChange` event.
|
|
1525
|
-
this._indexToSelect = this._selectedIndex = i;
|
|
1526
|
-
break;
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
this._subscribeToTabLabels();
|
|
1577
|
+
_checkPaginationEnabled() {
|
|
1578
|
+
/** @type {?} */
|
|
1579
|
+
const isEnabled = this._tabList.nativeElement.scrollWidth > this._elementRef.nativeElement.offsetWidth;
|
|
1580
|
+
if (!isEnabled) {
|
|
1581
|
+
this.scrollDistance = 0;
|
|
1582
|
+
}
|
|
1583
|
+
if (isEnabled !== this._showPaginationControls) {
|
|
1531
1584
|
this._changeDetectorRef.markForCheck();
|
|
1532
|
-
}
|
|
1585
|
+
}
|
|
1586
|
+
this._showPaginationControls = isEnabled;
|
|
1533
1587
|
}
|
|
1534
1588
|
/**
|
|
1589
|
+
* Evaluate whether the before and after controls should be enabled or disabled.
|
|
1590
|
+
* If the header is at the beginning of the list (scroll distance is equal to 0) then disable the
|
|
1591
|
+
* before button. If the header is at the end of the list (scroll distance is equal to the
|
|
1592
|
+
* maximum distance we can scroll), then disable the after button.
|
|
1593
|
+
*
|
|
1594
|
+
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
1595
|
+
* should be called sparingly.
|
|
1535
1596
|
* @return {?}
|
|
1536
1597
|
*/
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
this.
|
|
1598
|
+
_checkScrollingControls() {
|
|
1599
|
+
// Check if the pagination arrows should be activated.
|
|
1600
|
+
this._disableScrollBefore = this.scrollDistance == 0;
|
|
1601
|
+
this._disableScrollAfter = this.scrollDistance == this._getMaxScrollDistance();
|
|
1602
|
+
this._changeDetectorRef.markForCheck();
|
|
1540
1603
|
}
|
|
1541
1604
|
/**
|
|
1542
|
-
*
|
|
1605
|
+
* Determines what is the maximum length in pixels that can be set for the scroll distance. This
|
|
1606
|
+
* is equal to the difference in width between the tab list container and tab header container.
|
|
1607
|
+
*
|
|
1608
|
+
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
|
|
1609
|
+
* should be called sparingly.
|
|
1543
1610
|
* @return {?}
|
|
1544
1611
|
*/
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
}
|
|
1612
|
+
_getMaxScrollDistance() {
|
|
1613
|
+
/** @type {?} */
|
|
1614
|
+
const lengthOfTabList = this._tabList.nativeElement.scrollWidth;
|
|
1615
|
+
/** @type {?} */
|
|
1616
|
+
const viewLength = this._tabListContainer.nativeElement.offsetWidth;
|
|
1617
|
+
return (lengthOfTabList - viewLength) || 0;
|
|
1549
1618
|
}
|
|
1550
1619
|
/**
|
|
1551
|
-
*
|
|
1620
|
+
* Tells the ink-bar to align itself to the current label wrapper
|
|
1552
1621
|
* @return {?}
|
|
1553
1622
|
*/
|
|
1554
|
-
|
|
1555
|
-
|
|
1623
|
+
_alignInkBarToSelectedTab() {
|
|
1624
|
+
/** @type {?} */
|
|
1625
|
+
const selectedItem = this._items && this._items.length ?
|
|
1626
|
+
this._items.toArray()[this.selectedIndex] : null;
|
|
1627
|
+
/** @type {?} */
|
|
1628
|
+
const selectedLabelWrapper = selectedItem ? selectedItem.elementRef.nativeElement : null;
|
|
1629
|
+
if (selectedLabelWrapper) {
|
|
1630
|
+
this._inkBar.alignToElement(selectedLabelWrapper);
|
|
1631
|
+
}
|
|
1632
|
+
else {
|
|
1633
|
+
this._inkBar.hide();
|
|
1634
|
+
}
|
|
1556
1635
|
}
|
|
1557
1636
|
/**
|
|
1558
|
-
*
|
|
1559
|
-
* @param {?} index
|
|
1637
|
+
* Stops the currently-running paginator interval.
|
|
1560
1638
|
* @return {?}
|
|
1561
1639
|
*/
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
const event = new MatTabChangeEvent;
|
|
1565
|
-
event.index = index;
|
|
1566
|
-
if (this._tabs && this._tabs.length) {
|
|
1567
|
-
event.tab = this._tabs.toArray()[index];
|
|
1568
|
-
}
|
|
1569
|
-
return event;
|
|
1640
|
+
_stopInterval() {
|
|
1641
|
+
this._stopScrolling.next();
|
|
1570
1642
|
}
|
|
1571
1643
|
/**
|
|
1572
|
-
*
|
|
1573
|
-
*
|
|
1574
|
-
*
|
|
1575
|
-
* manually.
|
|
1576
|
-
* @private
|
|
1644
|
+
* Handles the user pressing down on one of the paginators.
|
|
1645
|
+
* Starts scrolling the header after a certain amount of time.
|
|
1646
|
+
* @param {?} direction In which direction the paginator should be scrolled.
|
|
1577
1647
|
* @return {?}
|
|
1578
1648
|
*/
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
*/
|
|
1587
|
-
tab => tab._stateChanges)))
|
|
1649
|
+
_handlePaginatorPress(direction) {
|
|
1650
|
+
// Avoid overlapping timers.
|
|
1651
|
+
this._stopInterval();
|
|
1652
|
+
// Start a timer after the delay and keep firing based on the interval.
|
|
1653
|
+
timer(HEADER_SCROLL_DELAY, HEADER_SCROLL_INTERVAL)
|
|
1654
|
+
// Keep the timer going until something tells it to stop or the component is destroyed.
|
|
1655
|
+
.pipe(takeUntil(merge(this._stopScrolling, this._destroyed)))
|
|
1588
1656
|
.subscribe((/**
|
|
1589
1657
|
* @return {?}
|
|
1590
1658
|
*/
|
|
1591
|
-
() =>
|
|
1659
|
+
() => {
|
|
1660
|
+
const { maxScrollDistance, distance } = this._scrollHeader(direction);
|
|
1661
|
+
// Stop the timer if we've reached the start or the end.
|
|
1662
|
+
if (distance === 0 || distance >= maxScrollDistance) {
|
|
1663
|
+
this._stopInterval();
|
|
1664
|
+
}
|
|
1665
|
+
}));
|
|
1592
1666
|
}
|
|
1593
1667
|
/**
|
|
1594
|
-
*
|
|
1668
|
+
* Scrolls the header to a given position.
|
|
1595
1669
|
* @private
|
|
1596
|
-
* @param {?}
|
|
1597
|
-
* @return {?}
|
|
1598
|
-
*/
|
|
1599
|
-
_clampTabIndex(index) {
|
|
1600
|
-
// Note the `|| 0`, which ensures that values like NaN can't get through
|
|
1601
|
-
// and which would otherwise throw the component into an infinite loop
|
|
1602
|
-
// (since Math.max(NaN, 0) === NaN).
|
|
1603
|
-
return Math.min(this._tabs.length - 1, Math.max(index || 0, 0));
|
|
1604
|
-
}
|
|
1605
|
-
/**
|
|
1606
|
-
* Returns a unique id for each tab label element
|
|
1607
|
-
* @param {?} i
|
|
1608
|
-
* @return {?}
|
|
1670
|
+
* @param {?} position Position to which to scroll.
|
|
1671
|
+
* @return {?} Information on the current scroll distance and the maximum.
|
|
1609
1672
|
*/
|
|
1610
|
-
|
|
1611
|
-
|
|
1673
|
+
_scrollTo(position) {
|
|
1674
|
+
/** @type {?} */
|
|
1675
|
+
const maxScrollDistance = this._getMaxScrollDistance();
|
|
1676
|
+
this._scrollDistance = Math.max(0, Math.min(maxScrollDistance, position));
|
|
1677
|
+
// Mark that the scroll distance has changed so that after the view is checked, the CSS
|
|
1678
|
+
// transformation can move the header.
|
|
1679
|
+
this._scrollDistanceChanged = true;
|
|
1680
|
+
this._checkScrollingControls();
|
|
1681
|
+
return { maxScrollDistance, distance: this._scrollDistance };
|
|
1612
1682
|
}
|
|
1683
|
+
}
|
|
1684
|
+
MatPaginatedTabHeader.decorators = [
|
|
1685
|
+
{ type: Directive, args: [{
|
|
1686
|
+
// TODO(crisbeto): this selector can be removed when we update to Angular 9.0.
|
|
1687
|
+
selector: 'do-not-use-abstract-mat-paginated-tab-header'
|
|
1688
|
+
},] },
|
|
1689
|
+
];
|
|
1690
|
+
/** @nocollapse */
|
|
1691
|
+
MatPaginatedTabHeader.ctorParameters = () => [
|
|
1692
|
+
{ type: ElementRef },
|
|
1693
|
+
{ type: ChangeDetectorRef },
|
|
1694
|
+
{ type: ViewportRuler },
|
|
1695
|
+
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
1696
|
+
{ type: NgZone },
|
|
1697
|
+
{ type: Platform },
|
|
1698
|
+
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
|
|
1699
|
+
];
|
|
1700
|
+
|
|
1701
|
+
/**
|
|
1702
|
+
* @fileoverview added by tsickle
|
|
1703
|
+
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1704
|
+
*/
|
|
1705
|
+
/**
|
|
1706
|
+
* Base class with all of the `MatTabHeader` functionality.
|
|
1707
|
+
* \@docs-private
|
|
1708
|
+
* @abstract
|
|
1709
|
+
*/
|
|
1710
|
+
// tslint:disable-next-line:class-name
|
|
1711
|
+
class _MatTabHeaderBase extends MatPaginatedTabHeader {
|
|
1613
1712
|
/**
|
|
1614
|
-
*
|
|
1615
|
-
* @param {?}
|
|
1616
|
-
* @
|
|
1713
|
+
* @param {?} elementRef
|
|
1714
|
+
* @param {?} changeDetectorRef
|
|
1715
|
+
* @param {?} viewportRuler
|
|
1716
|
+
* @param {?} dir
|
|
1717
|
+
* @param {?} ngZone
|
|
1718
|
+
* @param {?} platform
|
|
1719
|
+
* @param {?=} animationMode
|
|
1617
1720
|
*/
|
|
1618
|
-
|
|
1619
|
-
|
|
1721
|
+
constructor(elementRef, changeDetectorRef, viewportRuler, dir, ngZone, platform,
|
|
1722
|
+
// @breaking-change 9.0.0 `_animationMode` parameter to be made required.
|
|
1723
|
+
animationMode) {
|
|
1724
|
+
super(elementRef, changeDetectorRef, viewportRuler, dir, ngZone, platform, animationMode);
|
|
1725
|
+
this._disableRipple = false;
|
|
1620
1726
|
}
|
|
1621
1727
|
/**
|
|
1622
|
-
*
|
|
1623
|
-
* height property is true.
|
|
1624
|
-
* @param {?} tabHeight
|
|
1728
|
+
* Whether the ripple effect is disabled or not.
|
|
1625
1729
|
* @return {?}
|
|
1626
1730
|
*/
|
|
1627
|
-
|
|
1628
|
-
if (!this._dynamicHeight || !this._tabBodyWrapperHeight) {
|
|
1629
|
-
return;
|
|
1630
|
-
}
|
|
1631
|
-
/** @type {?} */
|
|
1632
|
-
const wrapper = this._tabBodyWrapper.nativeElement;
|
|
1633
|
-
wrapper.style.height = this._tabBodyWrapperHeight + 'px';
|
|
1634
|
-
// This conditional forces the browser to paint the height so that
|
|
1635
|
-
// the animation to the new height can have an origin.
|
|
1636
|
-
if (this._tabBodyWrapper.nativeElement.offsetHeight) {
|
|
1637
|
-
wrapper.style.height = tabHeight + 'px';
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1731
|
+
get disableRipple() { return this._disableRipple; }
|
|
1640
1732
|
/**
|
|
1641
|
-
*
|
|
1733
|
+
* @param {?} value
|
|
1642
1734
|
* @return {?}
|
|
1643
1735
|
*/
|
|
1644
|
-
|
|
1645
|
-
/** @type {?} */
|
|
1646
|
-
const wrapper = this._tabBodyWrapper.nativeElement;
|
|
1647
|
-
this._tabBodyWrapperHeight = wrapper.clientHeight;
|
|
1648
|
-
wrapper.style.height = '';
|
|
1649
|
-
this.animationDone.emit();
|
|
1650
|
-
}
|
|
1736
|
+
set disableRipple(value) { this._disableRipple = coerceBooleanProperty(value); }
|
|
1651
1737
|
/**
|
|
1652
|
-
*
|
|
1653
|
-
* @param {?}
|
|
1654
|
-
* @param {?} tabHeader
|
|
1655
|
-
* @param {?} index
|
|
1738
|
+
* @protected
|
|
1739
|
+
* @param {?} event
|
|
1656
1740
|
* @return {?}
|
|
1657
1741
|
*/
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
this.selectedIndex = tabHeader.focusIndex = index;
|
|
1661
|
-
}
|
|
1742
|
+
_itemSelected(event) {
|
|
1743
|
+
event.preventDefault();
|
|
1662
1744
|
}
|
|
1745
|
+
}
|
|
1746
|
+
_MatTabHeaderBase.decorators = [
|
|
1747
|
+
{ type: Directive, args: [{
|
|
1748
|
+
// TODO(crisbeto): this selector can be removed when we update to Angular 9.0.
|
|
1749
|
+
selector: 'do-not-use-abstract-mat-tab-header-base'
|
|
1750
|
+
},] },
|
|
1751
|
+
];
|
|
1752
|
+
/** @nocollapse */
|
|
1753
|
+
_MatTabHeaderBase.ctorParameters = () => [
|
|
1754
|
+
{ type: ElementRef },
|
|
1755
|
+
{ type: ChangeDetectorRef },
|
|
1756
|
+
{ type: ViewportRuler },
|
|
1757
|
+
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
1758
|
+
{ type: NgZone },
|
|
1759
|
+
{ type: Platform },
|
|
1760
|
+
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
|
|
1761
|
+
];
|
|
1762
|
+
_MatTabHeaderBase.propDecorators = {
|
|
1763
|
+
disableRipple: [{ type: Input }]
|
|
1764
|
+
};
|
|
1765
|
+
/**
|
|
1766
|
+
* The header of the tab group which displays a list of all the tabs in the tab group. Includes
|
|
1767
|
+
* an ink bar that follows the currently selected tab. When the tabs list's width exceeds the
|
|
1768
|
+
* width of the header container, then arrows will be displayed to allow the user to scroll
|
|
1769
|
+
* left and right across the header.
|
|
1770
|
+
* \@docs-private
|
|
1771
|
+
*/
|
|
1772
|
+
class MatTabHeader extends _MatTabHeaderBase {
|
|
1663
1773
|
/**
|
|
1664
|
-
*
|
|
1665
|
-
* @param {?}
|
|
1666
|
-
* @param {?}
|
|
1667
|
-
* @
|
|
1774
|
+
* @param {?} elementRef
|
|
1775
|
+
* @param {?} changeDetectorRef
|
|
1776
|
+
* @param {?} viewportRuler
|
|
1777
|
+
* @param {?} dir
|
|
1778
|
+
* @param {?} ngZone
|
|
1779
|
+
* @param {?} platform
|
|
1780
|
+
* @param {?=} animationMode
|
|
1668
1781
|
*/
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
return this.selectedIndex === idx ? 0 : -1;
|
|
1782
|
+
constructor(elementRef, changeDetectorRef, viewportRuler, dir, ngZone, platform,
|
|
1783
|
+
// @breaking-change 9.0.0 `_animationMode` parameter to be made required.
|
|
1784
|
+
animationMode) {
|
|
1785
|
+
super(elementRef, changeDetectorRef, viewportRuler, dir, ngZone, platform, animationMode);
|
|
1674
1786
|
}
|
|
1675
1787
|
}
|
|
1676
|
-
|
|
1677
|
-
{ type: Component, args: [{selector: 'mat-tab-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1788
|
+
MatTabHeader.decorators = [
|
|
1789
|
+
{ type: Component, args: [{selector: 'mat-tab-header',
|
|
1790
|
+
template: "<div class=\"mat-tab-header-pagination mat-tab-header-pagination-before mat-elevation-z4\" #previousPaginator aria-hidden=\"true\" mat-ripple [matRippleDisabled]=\"_disableScrollBefore || disableRipple\" [class.mat-tab-header-pagination-disabled]=\"_disableScrollBefore\" (click)=\"_handlePaginatorClick('before')\" (mousedown)=\"_handlePaginatorPress('before')\" (touchend)=\"_stopInterval()\"><div class=\"mat-tab-header-pagination-chevron\"></div></div><div class=\"mat-tab-label-container\" #tabListContainer (keydown)=\"_handleKeydown($event)\"><div #tabList class=\"mat-tab-list\" [class._mat-animation-noopable]=\"_animationMode === 'NoopAnimations'\" role=\"tablist\" (cdkObserveContent)=\"_onContentChanges()\"><div class=\"mat-tab-labels\"><ng-content></ng-content></div><mat-ink-bar></mat-ink-bar></div></div><div class=\"mat-tab-header-pagination mat-tab-header-pagination-after mat-elevation-z4\" #nextPaginator aria-hidden=\"true\" mat-ripple [matRippleDisabled]=\"_disableScrollAfter || disableRipple\" [class.mat-tab-header-pagination-disabled]=\"_disableScrollAfter\" (mousedown)=\"_handlePaginatorPress('after')\" (click)=\"_handlePaginatorClick('after')\" (touchend)=\"_stopInterval()\"><div class=\"mat-tab-header-pagination-chevron\"></div></div>",
|
|
1791
|
+
styles: [".mat-tab-header{display:flex;overflow:hidden;position:relative;flex-shrink:0}.mat-tab-header-pagination{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:none;justify-content:center;align-items:center;min-width:32px;cursor:pointer;z-index:2;-webkit-tap-highlight-color:transparent;touch-action:none}.mat-tab-header-pagination-controls-enabled .mat-tab-header-pagination{display:flex}.mat-tab-header-pagination-before,.mat-tab-header-rtl .mat-tab-header-pagination-after{padding-left:4px}.mat-tab-header-pagination-before .mat-tab-header-pagination-chevron,.mat-tab-header-rtl .mat-tab-header-pagination-after .mat-tab-header-pagination-chevron{transform:rotate(-135deg)}.mat-tab-header-pagination-after,.mat-tab-header-rtl .mat-tab-header-pagination-before{padding-right:4px}.mat-tab-header-pagination-after .mat-tab-header-pagination-chevron,.mat-tab-header-rtl .mat-tab-header-pagination-before .mat-tab-header-pagination-chevron{transform:rotate(45deg)}.mat-tab-header-pagination-chevron{border-style:solid;border-width:2px 2px 0 0;content:'';height:8px;width:8px}.mat-tab-header-pagination-disabled{box-shadow:none;cursor:default}.mat-tab-list{flex-grow:1;position:relative;transition:transform .5s cubic-bezier(.35,0,.25,1)}.mat-ink-bar{position:absolute;bottom:0;height:2px;transition:.5s cubic-bezier(.35,0,.25,1)}._mat-animation-noopable.mat-ink-bar{transition:none;animation:none}.mat-tab-group-inverted-header .mat-ink-bar{bottom:auto;top:0}@media (-ms-high-contrast:active){.mat-ink-bar{outline:solid 2px;height:0}}.mat-tab-labels{display:flex}[mat-align-tabs=center] .mat-tab-labels{justify-content:center}[mat-align-tabs=end] .mat-tab-labels{justify-content:flex-end}.mat-tab-label-container{display:flex;flex-grow:1;overflow:hidden;z-index:1}._mat-animation-noopable.mat-tab-list{transition:none;animation:none}.mat-tab-label{height:48px;padding:0 24px;cursor:pointer;box-sizing:border-box;opacity:.6;min-width:160px;text-align:center;display:inline-flex;justify-content:center;align-items:center;white-space:nowrap;position:relative}.mat-tab-label:focus{outline:0}.mat-tab-label:focus:not(.mat-tab-disabled){opacity:1}@media (-ms-high-contrast:active){.mat-tab-label:focus{outline:dotted 2px}}.mat-tab-label.mat-tab-disabled{cursor:default}@media (-ms-high-contrast:active){.mat-tab-label.mat-tab-disabled{opacity:.5}}.mat-tab-label .mat-tab-label-content{display:inline-flex;justify-content:center;align-items:center;white-space:nowrap}@media (-ms-high-contrast:active){.mat-tab-label{opacity:1}}@media (max-width:599px){.mat-tab-label{min-width:72px}}"],
|
|
1792
|
+
inputs: ['selectedIndex'],
|
|
1793
|
+
outputs: ['selectFocusedIndex', 'indexFocused'],
|
|
1681
1794
|
encapsulation: ViewEncapsulation.None,
|
|
1682
1795
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1683
|
-
inputs: ['color', 'disableRipple'],
|
|
1684
1796
|
host: {
|
|
1685
|
-
'class': 'mat-tab-
|
|
1686
|
-
'[class.mat-tab-
|
|
1687
|
-
'[class.mat-tab-
|
|
1797
|
+
'class': 'mat-tab-header',
|
|
1798
|
+
'[class.mat-tab-header-pagination-controls-enabled]': '_showPaginationControls',
|
|
1799
|
+
'[class.mat-tab-header-rtl]': "_getLayoutDirection() == 'rtl'",
|
|
1688
1800
|
},
|
|
1689
1801
|
},] },
|
|
1690
1802
|
];
|
|
1691
1803
|
/** @nocollapse */
|
|
1692
|
-
|
|
1804
|
+
MatTabHeader.ctorParameters = () => [
|
|
1693
1805
|
{ type: ElementRef },
|
|
1694
1806
|
{ type: ChangeDetectorRef },
|
|
1695
|
-
{ type:
|
|
1807
|
+
{ type: ViewportRuler },
|
|
1808
|
+
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
1809
|
+
{ type: NgZone },
|
|
1810
|
+
{ type: Platform },
|
|
1696
1811
|
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
|
|
1697
1812
|
];
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
animationDuration: [{ type: Input }],
|
|
1706
|
-
backgroundColor: [{ type: Input }],
|
|
1707
|
-
selectedIndexChange: [{ type: Output }],
|
|
1708
|
-
focusChange: [{ type: Output }],
|
|
1709
|
-
animationDone: [{ type: Output }],
|
|
1710
|
-
selectedTabChange: [{ type: Output }]
|
|
1813
|
+
MatTabHeader.propDecorators = {
|
|
1814
|
+
_items: [{ type: ContentChildren, args: [MatTabLabelWrapper,] }],
|
|
1815
|
+
_inkBar: [{ type: ViewChild, args: [MatInkBar, { static: true },] }],
|
|
1816
|
+
_tabListContainer: [{ type: ViewChild, args: ['tabListContainer', { static: true },] }],
|
|
1817
|
+
_tabList: [{ type: ViewChild, args: ['tabList', { static: true },] }],
|
|
1818
|
+
_nextPaginator: [{ type: ViewChild, args: ['nextPaginator', { static: false },] }],
|
|
1819
|
+
_previousPaginator: [{ type: ViewChild, args: ['previousPaginator', { static: false },] }]
|
|
1711
1820
|
};
|
|
1712
1821
|
|
|
1713
1822
|
/**
|
|
@@ -1715,10 +1824,12 @@ MatTabGroup.propDecorators = {
|
|
|
1715
1824
|
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
1716
1825
|
*/
|
|
1717
1826
|
/**
|
|
1718
|
-
*
|
|
1719
|
-
*
|
|
1827
|
+
* Base class with all of the `MatTabNav` functionality.
|
|
1828
|
+
* \@docs-private
|
|
1829
|
+
* @abstract
|
|
1720
1830
|
*/
|
|
1721
|
-
class
|
|
1831
|
+
// tslint:disable-next-line:class-name
|
|
1832
|
+
class _MatTabNavBase extends MatPaginatedTabHeader {
|
|
1722
1833
|
/**
|
|
1723
1834
|
* @param {?} elementRef
|
|
1724
1835
|
* @param {?} dir
|
|
@@ -1779,7 +1890,14 @@ class MatTabNav extends MatPaginatedTabHeader {
|
|
|
1779
1890
|
* @return {?}
|
|
1780
1891
|
*/
|
|
1781
1892
|
ngAfterContentInit() {
|
|
1782
|
-
this
|
|
1893
|
+
// We need this to run before the `changes` subscription in parent to ensure that the
|
|
1894
|
+
// selectedIndex is up-to-date by the time the super class starts looking for it.
|
|
1895
|
+
this._items.changes.pipe(startWith(null), takeUntil(this._destroyed)).subscribe((/**
|
|
1896
|
+
* @return {?}
|
|
1897
|
+
*/
|
|
1898
|
+
() => {
|
|
1899
|
+
this.updateActiveLink();
|
|
1900
|
+
}));
|
|
1783
1901
|
super.ngAfterContentInit();
|
|
1784
1902
|
}
|
|
1785
1903
|
/**
|
|
@@ -1806,6 +1924,49 @@ class MatTabNav extends MatPaginatedTabHeader {
|
|
|
1806
1924
|
this._inkBar.hide();
|
|
1807
1925
|
}
|
|
1808
1926
|
}
|
|
1927
|
+
_MatTabNavBase.decorators = [
|
|
1928
|
+
{ type: Directive, args: [{
|
|
1929
|
+
// TODO(crisbeto): this selector can be removed when we update to Angular 9.0.
|
|
1930
|
+
selector: 'do-not-use-abstract-mat-tab-nav-base'
|
|
1931
|
+
},] },
|
|
1932
|
+
];
|
|
1933
|
+
/** @nocollapse */
|
|
1934
|
+
_MatTabNavBase.ctorParameters = () => [
|
|
1935
|
+
{ type: ElementRef },
|
|
1936
|
+
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
1937
|
+
{ type: NgZone },
|
|
1938
|
+
{ type: ChangeDetectorRef },
|
|
1939
|
+
{ type: ViewportRuler },
|
|
1940
|
+
{ type: Platform, decorators: [{ type: Optional }] },
|
|
1941
|
+
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
|
|
1942
|
+
];
|
|
1943
|
+
_MatTabNavBase.propDecorators = {
|
|
1944
|
+
backgroundColor: [{ type: Input }],
|
|
1945
|
+
disableRipple: [{ type: Input }],
|
|
1946
|
+
color: [{ type: Input }]
|
|
1947
|
+
};
|
|
1948
|
+
/**
|
|
1949
|
+
* Navigation component matching the styles of the tab group header.
|
|
1950
|
+
* Provides anchored navigation with animated ink bar.
|
|
1951
|
+
*/
|
|
1952
|
+
class MatTabNav extends _MatTabNavBase {
|
|
1953
|
+
/**
|
|
1954
|
+
* @param {?} elementRef
|
|
1955
|
+
* @param {?} dir
|
|
1956
|
+
* @param {?} ngZone
|
|
1957
|
+
* @param {?} changeDetectorRef
|
|
1958
|
+
* @param {?} viewportRuler
|
|
1959
|
+
* @param {?=} platform
|
|
1960
|
+
* @param {?=} animationMode
|
|
1961
|
+
*/
|
|
1962
|
+
constructor(elementRef, dir, ngZone, changeDetectorRef, viewportRuler,
|
|
1963
|
+
/**
|
|
1964
|
+
* @deprecated @breaking-change 9.0.0 `platform` parameter to become required.
|
|
1965
|
+
*/
|
|
1966
|
+
platform, animationMode) {
|
|
1967
|
+
super(elementRef, dir, ngZone, changeDetectorRef, viewportRuler, platform, animationMode);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1809
1970
|
MatTabNav.decorators = [
|
|
1810
1971
|
{ type: Component, args: [{selector: '[mat-tab-nav-bar]',
|
|
1811
1972
|
exportAs: 'matTabNavBar, matTabNav',
|
|
@@ -1843,31 +2004,27 @@ MatTabNav.propDecorators = {
|
|
|
1843
2004
|
_tabListContainer: [{ type: ViewChild, args: ['tabListContainer', { static: true },] }],
|
|
1844
2005
|
_tabList: [{ type: ViewChild, args: ['tabList', { static: true },] }],
|
|
1845
2006
|
_nextPaginator: [{ type: ViewChild, args: ['nextPaginator', { static: false },] }],
|
|
1846
|
-
_previousPaginator: [{ type: ViewChild, args: ['previousPaginator', { static: false },] }]
|
|
1847
|
-
backgroundColor: [{ type: Input }],
|
|
1848
|
-
disableRipple: [{ type: Input }],
|
|
1849
|
-
color: [{ type: Input }]
|
|
2007
|
+
_previousPaginator: [{ type: ViewChild, args: ['previousPaginator', { static: false },] }]
|
|
1850
2008
|
};
|
|
1851
2009
|
// Boilerplate for applying mixins to MatTabLink.
|
|
1852
|
-
class
|
|
2010
|
+
class MatTabLinkMixinBase {
|
|
1853
2011
|
}
|
|
1854
2012
|
/** @type {?} */
|
|
1855
|
-
const _MatTabLinkMixinBase = mixinTabIndex(mixinDisableRipple(mixinDisabled(
|
|
2013
|
+
const _MatTabLinkMixinBase = mixinTabIndex(mixinDisableRipple(mixinDisabled(MatTabLinkMixinBase)));
|
|
1856
2014
|
/**
|
|
1857
|
-
*
|
|
2015
|
+
* Base class with all of the `MatTabLink` functionality.
|
|
1858
2016
|
*/
|
|
1859
|
-
class
|
|
2017
|
+
// tslint:disable-next-line:class-name
|
|
2018
|
+
class _MatTabLinkBase extends _MatTabLinkMixinBase {
|
|
1860
2019
|
/**
|
|
1861
2020
|
* @param {?} _tabNavBar
|
|
1862
2021
|
* @param {?} elementRef
|
|
1863
|
-
* @param {?} ngZone
|
|
1864
|
-
* @param {?} platform
|
|
1865
2022
|
* @param {?} globalRippleOptions
|
|
1866
2023
|
* @param {?} tabIndex
|
|
1867
2024
|
* @param {?} _focusMonitor
|
|
1868
2025
|
* @param {?=} animationMode
|
|
1869
2026
|
*/
|
|
1870
|
-
constructor(_tabNavBar, elementRef,
|
|
2027
|
+
constructor(_tabNavBar, elementRef, globalRippleOptions, tabIndex, _focusMonitor, animationMode) {
|
|
1871
2028
|
super();
|
|
1872
2029
|
this._tabNavBar = _tabNavBar;
|
|
1873
2030
|
this.elementRef = elementRef;
|
|
@@ -1876,8 +2033,6 @@ class MatTabLink extends _MatTabLinkMixinBase {
|
|
|
1876
2033
|
* Whether the tab link is active or not.
|
|
1877
2034
|
*/
|
|
1878
2035
|
this._isActive = false;
|
|
1879
|
-
this._tabLinkRipple = new RippleRenderer(this, ngZone, elementRef, platform);
|
|
1880
|
-
this._tabLinkRipple.setupTriggerEvents(elementRef.nativeElement);
|
|
1881
2036
|
this.rippleConfig = globalRippleOptions || {};
|
|
1882
2037
|
this.tabIndex = parseInt(tabIndex) || 0;
|
|
1883
2038
|
if (animationMode === 'NoopAnimations') {
|
|
@@ -1919,10 +2074,54 @@ class MatTabLink extends _MatTabLinkMixinBase {
|
|
|
1919
2074
|
* @return {?}
|
|
1920
2075
|
*/
|
|
1921
2076
|
ngOnDestroy() {
|
|
1922
|
-
this._tabLinkRipple._removeTriggerEvents();
|
|
1923
2077
|
this._focusMonitor.stopMonitoring(this.elementRef);
|
|
1924
2078
|
}
|
|
1925
2079
|
}
|
|
2080
|
+
_MatTabLinkBase.decorators = [
|
|
2081
|
+
{ type: Directive, args: [{
|
|
2082
|
+
// TODO(crisbeto): this selector can be removed when we update to Angular 9.0.
|
|
2083
|
+
selector: 'do-not-use-abstract-mat-tab-link-base'
|
|
2084
|
+
},] },
|
|
2085
|
+
];
|
|
2086
|
+
/** @nocollapse */
|
|
2087
|
+
_MatTabLinkBase.ctorParameters = () => [
|
|
2088
|
+
{ type: _MatTabNavBase },
|
|
2089
|
+
{ type: ElementRef },
|
|
2090
|
+
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_RIPPLE_GLOBAL_OPTIONS,] }] },
|
|
2091
|
+
{ type: String, decorators: [{ type: Attribute, args: ['tabindex',] }] },
|
|
2092
|
+
{ type: FocusMonitor },
|
|
2093
|
+
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
|
|
2094
|
+
];
|
|
2095
|
+
_MatTabLinkBase.propDecorators = {
|
|
2096
|
+
active: [{ type: Input }]
|
|
2097
|
+
};
|
|
2098
|
+
/**
|
|
2099
|
+
* Link inside of a `mat-tab-nav-bar`.
|
|
2100
|
+
*/
|
|
2101
|
+
class MatTabLink extends _MatTabLinkBase {
|
|
2102
|
+
/**
|
|
2103
|
+
* @param {?} tabNavBar
|
|
2104
|
+
* @param {?} elementRef
|
|
2105
|
+
* @param {?} ngZone
|
|
2106
|
+
* @param {?} platform
|
|
2107
|
+
* @param {?} globalRippleOptions
|
|
2108
|
+
* @param {?} tabIndex
|
|
2109
|
+
* @param {?} focusMonitor
|
|
2110
|
+
* @param {?=} animationMode
|
|
2111
|
+
*/
|
|
2112
|
+
constructor(tabNavBar, elementRef, ngZone, platform, globalRippleOptions, tabIndex, focusMonitor, animationMode) {
|
|
2113
|
+
super(tabNavBar, elementRef, globalRippleOptions, tabIndex, focusMonitor, animationMode);
|
|
2114
|
+
this._tabLinkRipple = new RippleRenderer(this, ngZone, elementRef, platform);
|
|
2115
|
+
this._tabLinkRipple.setupTriggerEvents(elementRef.nativeElement);
|
|
2116
|
+
}
|
|
2117
|
+
/**
|
|
2118
|
+
* @return {?}
|
|
2119
|
+
*/
|
|
2120
|
+
ngOnDestroy() {
|
|
2121
|
+
super.ngOnDestroy();
|
|
2122
|
+
this._tabLinkRipple._removeTriggerEvents();
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
1926
2125
|
MatTabLink.decorators = [
|
|
1927
2126
|
{ type: Directive, args: [{
|
|
1928
2127
|
selector: '[mat-tab-link], [matTabLink]',
|
|
@@ -1949,9 +2148,6 @@ MatTabLink.ctorParameters = () => [
|
|
|
1949
2148
|
{ type: FocusMonitor },
|
|
1950
2149
|
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
|
|
1951
2150
|
];
|
|
1952
|
-
MatTabLink.propDecorators = {
|
|
1953
|
-
active: [{ type: Input }]
|
|
1954
|
-
};
|
|
1955
2151
|
|
|
1956
2152
|
/**
|
|
1957
2153
|
* @fileoverview added by tsickle
|
|
@@ -1991,6 +2187,14 @@ MatTabsModule.decorators = [
|
|
|
1991
2187
|
MatTabBodyPortal,
|
|
1992
2188
|
MatTabHeader,
|
|
1993
2189
|
MatTabContent,
|
|
2190
|
+
(/** @type {?} */ (
|
|
2191
|
+
// TODO(crisbeto): these can be removed once they're turned into selector-less directives.
|
|
2192
|
+
MatPaginatedTabHeader)),
|
|
2193
|
+
(/** @type {?} */ (_MatTabGroupBase)),
|
|
2194
|
+
(/** @type {?} */ (_MatTabNavBase)),
|
|
2195
|
+
(/** @type {?} */ (_MatTabBodyBase)),
|
|
2196
|
+
(/** @type {?} */ (_MatTabHeaderBase)),
|
|
2197
|
+
(/** @type {?} */ (_MatTabLinkBase)),
|
|
1994
2198
|
],
|
|
1995
2199
|
},] },
|
|
1996
2200
|
];
|
|
@@ -2010,5 +2214,5 @@ MatTabsModule.decorators = [
|
|
|
2010
2214
|
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
2011
2215
|
*/
|
|
2012
2216
|
|
|
2013
|
-
export { MatInkBar, _MAT_INK_BAR_POSITIONER, MatTabBody, MatTabBodyPortal, MatTabHeader, MatTabLabelWrapper, MatTab, MatTabLabel, MatTabNav, MatTabLink,
|
|
2217
|
+
export { MatTabsModule, MatInkBar, _MAT_INK_BAR_POSITIONER, MatTabBody, _MatTabBodyBase, MatTabBodyPortal, MatTabHeader, _MatTabHeaderBase, MatTabLabelWrapper, MatTab, MatTabLabel, MatTabNav, MatTabLink, _MatTabNavBase, _MatTabLinkBase, MatTabContent, MatTabChangeEvent, MAT_TABS_CONFIG, _MatTabGroupBase, MatTabGroup, matTabsAnimations, _MAT_INK_BAR_POSITIONER_FACTORY as ɵa24, MatPaginatedTabHeader as ɵb24 };
|
|
2014
2218
|
//# sourceMappingURL=tabs.js.map
|