Nobody seems to have provided code samples so I will since I figured it out. Thanks to the other answer for the insight.
Here is how I am doing it.
Put this in some SCSS somewhere, either globally or wherever you need it (converting to basic CSS I will leave up to you if you need it that way):
mat-tab-group[vertical] {
flex-direction: row;
::ng-deep mat-tab-header {
flex-direction: column;
border-bottom: 0px solid transparent;
border-right: 1px solid rgba(0, 0, 0, 0.12);
.mat-tab-label-container {
flex-direction: column;
.mat-tab-labels {
flex-direction: column;
}
mat-ink-bar {
left: initial !important;
bottom: initial;
right: 0;
width: 2px !important;
height: initial;
}
}
}
::ng-deep .mat-tab-body-wrapper {
flex-direction: column;
width: 100%;
}
}
:host-context(.dark) mat-tab-group[vertical] ::ng-deep mat-tab-header {
border-right: 1px solid rgba(255, 255, 255, 0.12);
}
Now make the following changes to your component TS. You might want to put this in your main app component TS if you will use vertical tabs frequently. Otherwise add it to each relevant component.
First implement the DoCheck interface and add the following function:
ngDoCheck() {
document.querySelectorAll("mat-tab-group[vertical]").forEach((verticalTabGroup: HTMLElement) => {
let inkBar: HTMLElement = verticalTabGroup.querySelector("mat-ink-bar");
if (!inkBar) {
return;
}
let active: HTMLElement = verticalTabGroup.querySelector(".mat-tab-label-active");
if (!active) {
return;
}
inkBar.style.top = `${active.offsetTop}px`;
inkBar.style.height = `${active.offsetHeight}px`;
});
}
Maybe there's a better way to do this in angular, I'm afraid I've got an old school vanilla background and I'm still learning,
One thing missing is the body still scrolls horizontally when you change tabs. This seems to be done using JS by brute forcing CSS transform styles so it can't be adjusted without modifying the original mat-tab-group source.
Keep in mind I only did basic testing with a simple tab group. I am not sure if the pagination arrows will work properly with this. I'll leave that as an exercise for the developer who needs it.
Another exercise for anyone curious: Perhaps it may be possible to rotate the entire tab group with a CSS transform, then rotate the tab labels and tab bodies back to turn the whole thing vertical. this would allow the ink bar and body transitions to work as-is, in theory. But it's probably overkill.