Reputation: 13846
Using the proper Angular Material directive, how do I change the direction to vertical?
Starting with vertical tabs:
Then want to drop to content below mat-select dropdown:
EDIT: Will be working on adapting https://stackoverflow.com/a/43389018 into my answer, if someone doesn't beat me to it :)
Upvotes: 22
Views: 55629
Reputation: 1701
Came across this question while looking for a simple solution. So will post what i found for future seekers.
If you're following Material Design's principles, don't do it. Angular Material's team didn't add it due to the need of adding tabs on top of each other, which is discouraged by Material Design spec, as shown below.
Obviously this answer was totally based in crisbeto's response, which can be found in issue #21067 from angular components repository.
You can still change header position with headerPosition
as shown here (actually only supports above or below)
i.e.:
<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>
Upvotes: 0
Reputation: 11630
I have created a vertical tab, I feel this is a better one.
app.component.html
<mat-tab-group [@.disabled]="true" >
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>home</mat-icon>Home
</ng-template>
<div>Content 1</div>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>login</mat-icon>Login
</ng-template>
Content 2
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>code</mat-icon>Code
</ng-template>
Content 3
</mat-tab>
</mat-tab-group>
app.component.css
:host {
display: flex;
flex-direction: column;
overflow: hidden;
}
:host ::ng-deep .mat-tab-labels {
flex-direction: column;
}
mat-tab-group {
flex-grow: 1;
display: flex;
flex-direction: row;
}
:host ::ng-deep .mat-tab-body-wrapper {
flex-grow: 1;
display: flex;
flex-direction: column;
}
mat-tab-body {
flex-grow: 1;
display: flex;
flex-direction: column;
}
:host ::ng-deep mat-ink-bar {
display: none;
}
/* Styles for the active tab label */
:host ::ng-deep.mat-tab-label.mat-tab-label-active {
background-color: transparent;
color: red;
background-color: yellow;
border-right: 2px solid red;
}
/* Styles for the active tab label */
:host ::ng-deep.mat-tab-label {
background-color: transparent;
/* background-color: lightgray; */
}
Screenshot:
Stackblitz Demo: https://stackblitz.com/edit/angular-verticall-tabs
Upvotes: 2
Reputation: 11630
Use the below code for the vertical tab using angular material.
HTML
<div class="container">
<div id="content">
<div id="main-content">
<mat-tab-group>
<mat-tab label="Tab One">
Tab One Content
</mat-tab>
<mat-tab label="Tab Two">
Tab Two Content
</mat-tab>
</mat-tab-group>
</div>
</div>
</div>
SCSS
:host {
>.container {
max-width: 1264px;
width: 100%;
margin: 0 auto;
display: flex;
justify-content: space-between;
background: none;
}
/deep/ {
.mat-tab-group {
flex-direction: row;
}
.mat-tab-header {
border-bottom: none;
}
.mat-tab-header-pagination {
display: none !important;
}
.mat-tab-labels {
flex-direction: column;
}
.mat-ink-bar {
height: 100%;
left: 98% !important;
}
.mat-tab-body-wrapper {
flex: 1 1 auto;
}
}
}
.container {
position: relative;
width: 100%;
flex: 1 0 auto;
margin: 0 auto;
text-align: left;
}
#content {
box-sizing: content-box;
margin: 0 auto;
padding: 15px;
width: 1264px;
background-color: #ffffff;
}
#content {
max-width: 1100px;
width: 100%;
background-color: #ffffff;
padding: 24px;
box-sizing: border-box;
}
#content,
#main-content {
&::before,
&::after {
content: "";
display: table;
}
&::after {
clear: both;
}
}
Stackblitz Demo here
Upvotes: 3
Reputation: 1307
So this is not perfect in my opinion but its very little code, does the trick and seems to work well with the other features of mat-tabs.
.mat-tab-group {
flex-direction: row !important;
}
.mat-tab-labels {
flex-direction: column !important;
}
.mat-tab-label-active {
border-right: 2px solid $primary-color !important;
}
.mat-ink-bar {
display: none;
}
Since the relevant classes are rendered outside the scope of the component, you will have to set encapsulation to ViewEncapsulation.None, note: this might meddle with the component styles.
This obviously does not solve the lack of animation but for me it was enough that the active strips gets highlighted which I achieved by simply hiding the original ink-bar and adding a border which mimics it
Upvotes: 7
Reputation: 1093
I am very new to Angular and tried to create vertical tabs using tabs, Sidenav and mat-action-list. I had to create separate component for tabs with hidden headers (because of ViewEncapsulation.None usage)
I don't know how to create stackblitz content yet. Here is very basic implementation. Hope it helps someone.
app.component.html
<mat-sidenav-container class="side-nav-container">
<mat-sidenav mode="side" opened class="sidenav">
<mat-action-list>
<button mat-list-item (click)="index = 0"> tab 1 </button>
<button mat-list-item (click)="index = 1"> tab 2 </button>
</mat-action-list>
</mat-sidenav>
<mat-sidenav-content>
<app-tab-content [(index)]=index></app-tab-content>
</mat-sidenav-content>
</mat-sidenav-container>
app.component.css
.side-nav-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: #eee;
}
.sidenav {
width: 200px;
background: rgb(15,62,9);
}
mat-action-list .mat-list-item {
color : white;
}
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
index: number;
}
tab-content.component.html
<mat-tab-group [(selectedIndex)]="index" class="header-less-tabs" animationDuration="0ms">
<mat-tab> Content 1 </mat-tab>
<mat-tab> Content 2 </mat-tab>
</mat-tab-group>
tab-content.component.css
.header-less-tabs.mat-tab-group .mat-tab-header {
display: none;
}
tab-content.component.ts
import { Component, OnInit, ViewEncapsulation, Input } from '@angular/core';
@Component({
selector: 'app-tab-content',
templateUrl: './tab-content.component.html',
styleUrls: ['./tab-content.component.css'],
encapsulation: ViewEncapsulation.None
})
export class TabContentComponent {
@Input() index: number = 1;
}
Upvotes: 5
Reputation: 1884
Wrote angular-vertical-tabs. This simply wraps @angular/material
's mat-selection-list
, and uses @angular/flex-layout
to reorient for different screens sizes.
<vertical-tabs>
<vertical-tab tabTitle="Tab 0">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Mauris tincidunt mattis neque lacinia dignissim.
Morbi ex orci, bibendum et varius vel, porttitor et magna.
</vertical-tab>
<vertical-tab tabTitle="Tab b">
Curabitur efficitur eleifend nulla, eget porta diam sodales in.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas vestibulum libero lacus, et porta ex tincidunt quis.
</vertical-tab>
<vertical-tab tabTitle="Tab 2">
Sed dictum, diam et vehicula sollicitudin, eros orci viverra diam, et pretium
risus nisl eget ex. Integer lacinia commodo ipsum, sit amet consectetur magna
hendrerit eu.
</vertical-tab>
</vertical-tabs>
Upvotes: 6