Skip to content

Commit

Permalink
prototype(tabs): create prototype tabs based on MDC web (#16805)
Browse files Browse the repository at this point in the history
Adds an implementation of the Angular Material tabs that is based on MDC web. The API is exactly the same, except for a couple of differences:

1. The ink bar has been switched to use MDC's `tab-indicator`. As such the styling and the animation are slightly different.
2. Previously `MatTabLink` used to be a `Directive`, however now it's a `Component`, because we need some extra markup around the content.
  • Loading branch information
crisbeto authored and jelbourn committed Sep 9, 2019
1 parent 8a4bed5 commit 492fdcc
Show file tree
Hide file tree
Showing 48 changed files with 4,043 additions and 210 deletions.
1 change: 1 addition & 0 deletions src/dev-app/mdc-tabs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ ng_module(
],
deps = [
"//src/material-experimental/mdc-tabs",
"//src/material/button-toggle",
"@npm//@angular/router",
],
)
Expand Down
4 changes: 4 additions & 0 deletions src/dev-app/mdc-tabs/mdc-tabs-demo-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@
import {NgModule} from '@angular/core';
import {MatTabsModule} from '@angular/material-experimental/mdc-tabs';
import {RouterModule} from '@angular/router';
import {CommonModule} from '@angular/common';
import {MdcTabsDemo} from './mdc-tabs-demo';
import {MatButtonToggleModule} from '@angular/material/button-toggle';

@NgModule({
imports: [
MatTabsModule,
RouterModule.forChild([{path: '', component: MdcTabsDemo}]),
CommonModule,
MatButtonToggleModule,
],
declarations: [MdcTabsDemo],
})
Expand Down
115 changes: 113 additions & 2 deletions src/dev-app/mdc-tabs/mdc-tabs-demo.html
Original file line number Diff line number Diff line change
@@ -1,2 +1,113 @@
<!-- TODO: copy in demo template from existing tabs demo. -->
Not yet implemented.
<div class="mat-typography">
<h2>Paginated tabs</h2>
<mat-tab-group>
<mat-tab [label]="tab" *ngFor="let tab of lotsOfTabs">Content</mat-tab>
</mat-tab-group>

<h2>Themed tabs</h2>
<mat-tab-group [color]="'primary'">
<mat-tab label="First">Content 1</mat-tab>
<mat-tab label="Second">Content 2</mat-tab>
<mat-tab label="Third">Content 3</mat-tab>
<mat-tab label="Fourth" disabled>Content 4</mat-tab>
</mat-tab-group>

<mat-tab-group [color]="'accent'">
<mat-tab label="First">Content 1</mat-tab>
<mat-tab label="Second">Content 2</mat-tab>
<mat-tab label="Third">Content 3</mat-tab>
<mat-tab label="Fourth" disabled>Content 4</mat-tab>
</mat-tab-group>

<mat-tab-group [color]="'warn'">
<mat-tab label="First">Content 1</mat-tab>
<mat-tab label="Second">Content 2</mat-tab>
<mat-tab label="Third">Content 3</mat-tab>
<mat-tab label="Fourth" disabled>Content 4</mat-tab>
</mat-tab-group>

<h2>Stretched tabs</h2>
<mat-tab-group mat-stretch-tabs>
<mat-tab label="First">Content 1</mat-tab>
<mat-tab label="Second">Content 2</mat-tab>
<mat-tab label="Third">Content 3</mat-tab>
</mat-tab-group>

<h2>Aligned tabs</h2>
<mat-tab-group mat-align-tabs="start">
<mat-tab label="First">Content 1</mat-tab>
<mat-tab label="Second">Content 2</mat-tab>
<mat-tab label="Third">Content 3</mat-tab>
</mat-tab-group>

<mat-tab-group mat-align-tabs="center">
<mat-tab label="First">Content 1</mat-tab>
<mat-tab label="Second">Content 2</mat-tab>
<mat-tab label="Third">Content 3</mat-tab>
</mat-tab-group>

<mat-tab-group mat-align-tabs="end">
<mat-tab label="First">Content 1</mat-tab>
<mat-tab label="Second">Content 2</mat-tab>
<mat-tab label="Third">Content 3</mat-tab>
</mat-tab-group>

<h2>Inverted tabs</h2>
<mat-tab-group headerPosition="below">
<mat-tab label="First">Content 1</mat-tab>
<mat-tab label="Second">Content 2</mat-tab>
<mat-tab label="Third">Content 3</mat-tab>
</mat-tab-group>

<h2>Tabs with background color</h2>
<div>
<mat-button-toggle-group #backgroundColorToggle="matButtonToggleGroup"
value="primary"
aria-label="Change color">
<mat-button-toggle value="primary">Primary</mat-button-toggle>
<mat-button-toggle value="accent">Accent</mat-button-toggle>
<mat-button-toggle value="warn">Warn</mat-button-toggle>
</mat-button-toggle-group>
</div>

<mat-tab-group [backgroundColor]="backgroundColorToggle.value">
<mat-tab [label]="tab" *ngFor="let tab of lotsOfTabs">Content</mat-tab>
</mat-tab-group>

<h2>Template labels</h2>

<mat-tab-group>
<mat-tab>
<ng-template mat-tab-label>One</ng-template>
First tab's content
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>Two</ng-template>
Second tab's content
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>Three</ng-template>
Third tab's content
</mat-tab>
</mat-tab-group>

<h2>Lazy tabs</h2>
<mat-tab-group>
<mat-tab label="One">
Eager
</mat-tab>
<mat-tab label="Two">
<ng-template matTabContent>
<div class="child">Lazy</div>
</ng-template>
</mat-tab>
</mat-tab-group>

<h2>Tab nav bar</h2>
<nav mat-tab-nav-bar>
<a mat-tab-link *ngFor="let link of links"
(click)="activeLink = link"
[active]="activeLink == link">{{link}}</a>
<a mat-tab-link disabled>Disabled Link</a>
</nav>
</div>
4 changes: 3 additions & 1 deletion src/dev-app/mdc-tabs/mdc-tabs-demo.scss
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
// TODO: copy in demo styles from existing tabs demo.
mat-tab-group {
margin-bottom: 32px;
}
3 changes: 3 additions & 0 deletions src/dev-app/mdc-tabs/mdc-tabs-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ import {Component} from '@angular/core';
styleUrls: ['mdc-tabs-demo.css'],
})
export class MdcTabsDemo {
links = ['First', 'Second', 'Third'];
lotsOfTabs = new Array(30).fill(0).map((_, index) => `Tab ${index}`);
activeLink = this.links[0];
}
4 changes: 3 additions & 1 deletion src/e2e-app/mdc-tabs/mdc-tabs-e2e-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
*/

import {NgModule} from '@angular/core';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatInputModule} from '@angular/material/input';
import {MatTabsModule} from '@angular/material-experimental/mdc-tabs';
import {MdcTabsE2e} from './mdc-tabs-e2e';

@NgModule({
imports: [MatTabsModule],
imports: [MatTabsModule, MatFormFieldModule, MatInputModule],
declarations: [MdcTabsE2e],
})
export class MdcTabsE2eModule {
Expand Down
19 changes: 18 additions & 1 deletion src/e2e-app/mdc-tabs/mdc-tabs-e2e.html
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
<!-- TODO: copy implementation from existing tabs e2e page. -->
<section>
<mat-tab-group>
<mat-tab>
<ng-template mat-tab-label>One</ng-template>
<mat-form-field>
<textarea matInput placeholder="Autosize textarea" cdkTextareaAutosize>This is an autosize textarea, it should adjust to the size of its content.</textarea>
</mat-form-field>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>Two</ng-template>
Second tab's content
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>Three</ng-template>
Third tab's content
</mat-tab>
</mat-tab-group>
</section>
1 change: 0 additions & 1 deletion src/e2e-app/mdc-tabs/mdc-tabs-e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ import {Component} from '@angular/core';
templateUrl: 'mdc-tabs-e2e.html',
})
export class MdcTabsE2e {
// TODO: copy implementation from existing tabs e2e page.
}
100 changes: 91 additions & 9 deletions src/material-experimental/mdc-tabs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,38 @@ package(default_visibility = ["//visibility:public"])

load("@io_bazel_rules_sass//:defs.bzl", "sass_binary", "sass_library")
load("//src/e2e-app:test_suite.bzl", "e2e_test_suite")
load("//tools:defaults.bzl", "ng_e2e_test_library", "ng_module")
load("//tools:defaults.bzl", "ng_e2e_test_library", "ng_module", "ng_test_library", "ng_web_test_suite")

ng_module(
name = "mdc-tabs",
srcs = glob(
["**/*.ts"],
exclude = ["**/*.spec.ts"],
),
assets = [":tabs_scss"] + glob(["**/*.html"]),
assets = [
":tabs_scss",
":tab-body.css",
":tab-header.css",
":tab-group.css",
":tab-nav-bar/tab-nav-bar.css",
":tab-nav-bar/tab-link.css",
] + glob(["**/*.html"]),
module_name = "@angular/material-experimental/mdc-tabs",
deps = [
"//src/cdk/a11y",
"//src/cdk/bidi",
"//src/cdk/coercion",
"//src/cdk/keycodes",
"//src/cdk/observers",
"//src/cdk/platform",
"//src/cdk/portal",
"//src/cdk/scrolling",
"//src/material/core",
"//src/material/tabs",
"@npm//@angular/animations",
"@npm//@angular/common",
"@npm//@angular/core",
"@npm//@material/tab-indicator",
],
)

Expand All @@ -30,21 +48,85 @@ sass_library(

sass_binary(
name = "tabs_scss",
src = "tabs.scss",
include_paths = [
"external/npm/node_modules",
],
src = "_mdc-tabs.scss",
include_paths = ["external/npm/node_modules"],
deps = [
"//src/material-experimental/mdc-helpers:mdc_helpers_scss_lib",
"//src/material-experimental/mdc-helpers:mdc_scss_deps_lib",
],
)

sass_binary(
name = "mdc_tab_body_scss",
src = "tab-body.scss",
include_paths = ["external/npm/node_modules"],
deps = ["//src/material/core:core_scss_lib"],
)

sass_binary(
name = "mdc_tab_header_scss",
src = "tab-header.scss",
include_paths = ["external/npm/node_modules"],
deps = [":mdc_tabs_scss_lib"],
)

sass_binary(
name = "mdc_tab_group_scss",
src = "tab-group.scss",
include_paths = ["external/npm/node_modules"],
deps = [":mdc_tabs_scss_lib"],
)

sass_binary(
name = "mdc_tab_nav_bar_scss",
src = "tab-nav-bar/tab-nav-bar.scss",
include_paths = ["external/npm/node_modules"],
deps = [":mdc_tabs_scss_lib"],
)

sass_binary(
name = "mdc_tab_link_scss",
src = "tab-nav-bar/tab-link.scss",
include_paths = ["external/npm/node_modules"],
deps = [":mdc_tabs_scss_lib"],
)

ng_test_library(
name = "tabs_tests_lib",
srcs = glob(
["**/*.spec.ts"],
exclude = ["**/*.e2e.spec.ts"],
),
deps = [
":mdc-tabs",
"//src/cdk-experimental/testing",
"//src/cdk-experimental/testing/testbed",
"//src/cdk/bidi",
"//src/cdk/keycodes",
"//src/cdk/observers",
"//src/cdk/portal",
"//src/cdk/scrolling",
"//src/cdk/testing",
"//src/material/core",
"@npm//@angular/common",
"@npm//@angular/platform-browser",
"@npm//rxjs",
],
)

ng_web_test_suite(
name = "unit_tests",
static_files = ["@npm//:node_modules/@material/tab-indicator/dist/mdc.tabIndicator.js"],
deps = [
":tabs_tests_lib",
"//src/material-experimental:mdc_require_config.js",
],
)

ng_e2e_test_library(
name = "e2e_test_sources",
srcs = glob(["**/*.e2e.spec.ts"]),
deps = [
"//src/cdk/private/testing/e2e",
],
deps = ["//src/cdk/private/testing/e2e"],
)

e2e_test_suite(
Expand Down
Loading

0 comments on commit 492fdcc

Please sign in to comment.