Skip to content

Commit

Permalink
feat(kit): Tabs add vertical option (#2862)
Browse files Browse the repository at this point in the history
  • Loading branch information
waterplea authored Oct 11, 2022
1 parent 79e14c8 commit a0513c8
Show file tree
Hide file tree
Showing 14 changed files with 313 additions and 53 deletions.
2 changes: 1 addition & 1 deletion projects/demo/src/modules/app/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ export const pages: TuiDocPages = [
{
section: $localize`Navigation`,
title: `Tabs`,
keywords: `mobile, ios, android, шаги, таб, tab, tabs`,
keywords: `mobile, ios, android, шаги, таб, tab, tabs, vertical`,
route: `/navigation/tabs`,
},
// Customization
Expand Down
78 changes: 78 additions & 0 deletions projects/demo/src/modules/components/tabs/examples/8/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<section class="content">
<nav
tuiTabs
vertical="left"
class="left"
>
<button tuiTab>Item 1</button>
<button tuiTab>Item 2</button>
<button tuiTab>Item 3 with name so long it spans multiple lines</button>
</nav>
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce nec ultricies enim, vel molestie orci. In
finibus diam ac nulla accumsan, vel condimentum lorem ultricies. In feugiat mauris sem, ac ultricies metus
aliquet nec. Ut a iaculis metus, id vestibulum justo. Nulla id ante semper, aliquam augue vitae,
sollicitudin massa. Sed congue nisi sed ullamcorper mollis. Vivamus volutpat non est a vestibulum. Sed in
elementum odio. Proin a lectus ac quam vulputate ornare nec id mi. Maecenas pharetra ultricies efficitur.
Etiam sit amet vulputate elit. Donec ut dapibus nunc. Nullam vestibulum diam eros, ac euismod velit porta
ac. Ut ut auctor velit. Nulla ac lobortis erat, ut tempor neque.
</p>
<p>
Donec quis lacus leo. Mauris quis vestibulum mauris. Sed hendrerit odio id blandit iaculis. Nulla ac gravida
ligula, tristique tempus eros. Mauris efficitur risus quis arcu pharetra, eu semper ex rutrum. Aenean justo
felis, imperdiet non justo vel, fringilla maximus nibh. Vestibulum ut imperdiet ex, vel varius odio. Nunc
nec lorem non odio mollis porta. In gravida accumsan lacus, vitae egestas lectus aliquet sed. Morbi justo
orci, fringilla sit amet consectetur vel, consectetur a nibh. Sed eu porttitor ante. Morbi imperdiet ligula
id velit dignissim malesuada. Vestibulum blandit posuere sem.
</p>
</div>
</section>

<section class="content">
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce nec ultricies enim, vel molestie orci. In
finibus diam ac nulla accumsan, vel condimentum lorem ultricies. In feugiat mauris sem, ac ultricies metus
aliquet nec. Ut a iaculis metus, id vestibulum justo. Nulla id ante semper, aliquam augue vitae,
sollicitudin massa. Sed congue nisi sed ullamcorper mollis. Vivamus volutpat non est a vestibulum. Sed in
elementum odio. Proin a lectus ac quam vulputate ornare nec id mi. Maecenas pharetra ultricies efficitur.
Etiam sit amet vulputate elit. Donec ut dapibus nunc. Nullam vestibulum diam eros, ac euismod velit porta
ac. Ut ut auctor velit. Nulla ac lobortis erat, ut tempor neque.
</p>
<p>
Donec quis lacus leo. Mauris quis vestibulum mauris. Sed hendrerit odio id blandit iaculis. Nulla ac gravida
ligula, tristique tempus eros. Mauris efficitur risus quis arcu pharetra, eu semper ex rutrum. Aenean justo
felis, imperdiet non justo vel, fringilla maximus nibh. Vestibulum ut imperdiet ex, vel varius odio. Nunc
nec lorem non odio mollis porta. In gravida accumsan lacus, vitae egestas lectus aliquet sed. Morbi justo
orci, fringilla sit amet consectetur vel, consectetur a nibh. Sed eu porttitor ante. Morbi imperdiet ligula
id velit dignissim malesuada. Vestibulum blandit posuere sem.
</p>
</div>
<tui-tabs
vertical="right"
class="right"
>
<a
tuiTab
routerLink="/components/button"
routerLinkActive
>
Button
</a>
<a
tuiTab
routerLink="/navigation/tabs"
routerLinkActive
>
Tabs
</a>
<a
tuiTab
routerLink="/components/input"
routerLinkActive
>
Input
</a>
</tui-tabs>
</section>
16 changes: 16 additions & 0 deletions projects/demo/src/modules/components/tabs/examples/8/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.content {
display: flex;
margin: 2rem 0;
}

.left {
margin-right: 2rem;
min-width: 10rem;
width: 10rem;
}

.right {
margin-left: 2rem;
min-width: 10rem;
width: 10rem;
}
12 changes: 12 additions & 0 deletions projects/demo/src/modules/components/tabs/examples/8/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Component} from '@angular/core';
import {changeDetection} from '@demo/emulate/change-detection';
import {encapsulation} from '@demo/emulate/encapsulation';

@Component({
selector: `tui-tabs-example-8`,
templateUrl: `./index.html`,
styleUrls: [`./index.less`],
changeDetection,
encapsulation,
})
export class TuiTabsExample8 {}
6 changes: 6 additions & 0 deletions projects/demo/src/modules/components/tabs/tabs.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ export class ExampleTuiTabsComponent {
HTML: import(`./examples/7/index.html?raw`),
};

readonly example8: TuiDocExample = {
TypeScript: import(`./examples/8/index.ts?raw`),
HTML: import(`./examples/8/index.html?raw`),
LESS: import(`./examples/8/index.less?raw`),
};

readonly moreContentVariants = [``, `And more`];

moreContent = this.moreContentVariants[0];
Expand Down
2 changes: 2 additions & 0 deletions projects/demo/src/modules/components/tabs/tabs.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {TuiTabsExample4} from './examples/4';
import {TuiTabsExample5} from './examples/5';
import {TuiTabsExample6} from './examples/6';
import {TuiTabsExample7} from './examples/7';
import {TuiTabsExample8} from './examples/8';
import {ExampleTuiTabsComponent} from './tabs.component';

@NgModule({
Expand Down Expand Up @@ -49,6 +50,7 @@ import {ExampleTuiTabsComponent} from './tabs.component';
TuiTabsExample5,
TuiTabsExample6,
TuiTabsExample7,
TuiTabsExample8,
],
exports: [ExampleTuiTabsComponent],
})
Expand Down
8 changes: 8 additions & 0 deletions projects/demo/src/modules/components/tabs/tabs.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@
<tui-tabs-example-7></tui-tabs-example-7>
</tui-doc-example>

<tui-doc-example
id="vertical"
heading="Vertical"
[content]="example8"
>
<tui-tabs-example-8></tui-tabs-example-8>
</tui-doc-example>

<tui-doc-example
id="android"
heading="Android"
Expand Down
2 changes: 2 additions & 0 deletions projects/kit/components/tabs/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
export * from './tab/tab.component';
export * from './tab/tab.providers';
export * from './tabs.directive';
export * from './tabs.module';
export * from './tabs/tabs.component';
export * from './tabs-options';
export * from './tabs-vertical/tabs-vertical.component';
export * from './tabs-with-more/tabs-with-more.component';
export * from './tabs-with-more/tabs-with-more.providers';
export * from './underline/underline.component';
47 changes: 47 additions & 0 deletions projects/kit/components/tabs/tab/tab.style.less
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,50 @@
flex-shrink: 0;
}
}

:host-context(tui-tabs[data-vertical]),
:host-context([tuiTabs][data-vertical]) {
min-height: 2.75rem;
height: auto;
white-space: normal;
margin: 0;
text-align: left;
padding: 0.25rem 1.25rem 0.25rem 0;

&:after {
.transition(transform);
content: '';
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: 2px;
background: var(--tui-primary);
transform: scaleX(0);
transform-origin: right;
}

&:hover {
box-shadow: inset -2px 0 var(--tui-base-03);
}

&._active:after {
transform: none;
}
}

:host-context(tui-tabs[data-vertical='right']),
:host-context([tuiTabs][data-vertical='right']) {
text-align: right;
padding: 0.25rem 0 0.25rem 1.25rem;

&:after {
right: auto;
left: 0;
transform-origin: left;
}

&:hover {
box-shadow: inset 2px 0 var(--tui-base-03);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
ChangeDetectionStrategy,
Component,
HostBinding,
HostListener,
Inject,
Input,
} from '@angular/core';
import {tuiDefaultProp} from '@taiga-ui/cdk';
import {TuiHorizontalDirection} from '@taiga-ui/core';

import {TuiTabsDirective} from '../tabs.directive';

@Component({
selector: `tui-tabs[vertical], nav[tuiTabs][vertical]`,
template: `
<ng-content></ng-content>
`,
styleUrls: [`./tabs-vertical.style.less`],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TuiTabsVerticalComponent {
@Input()
@HostBinding(`attr.data-vertical`)
@tuiDefaultProp()
vertical: TuiHorizontalDirection = `left`;

constructor(@Inject(TuiTabsDirective) private readonly tabs: TuiTabsDirective) {}

@HostListener(`keydown.arrowDown.prevent`, [`$event.target`, `1`])
@HostListener(`keydown.arrowUp.prevent`, [`$event.target`, `-1`])
onKeyDownArrow(current: HTMLElement, step: number): void {
this.tabs.moveFocus(current, step);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@import 'taiga-ui-local';

:host {
display: flex;
flex-direction: column;
font: var(--tui-font-text-m);
color: var(--tui-text-02);
box-shadow: inset -1px 0 var(--tui-base-03);

&[data-vertical='right'] {
box-shadow: inset 1px 0 var(--tui-base-03);
}
}
68 changes: 68 additions & 0 deletions projects/kit/components/tabs/tabs.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import {
AfterViewChecked,
Directive,
ElementRef,
EventEmitter,
HostListener,
Inject,
Input,
Output,
} from '@angular/core';
import {tuiDefaultProp, tuiMoveFocus} from '@taiga-ui/cdk';

import {TUI_TAB_ACTIVATE} from './tab/tab.providers';

@Directive({
selector: `tui-tabs, nav[tuiTabs]`,
})
export class TuiTabsDirective implements AfterViewChecked {
@Input()
@tuiDefaultProp()
activeItemIndex = 0;

@Output()
readonly activeItemIndexChange = new EventEmitter<number>();

constructor(
@Inject(ElementRef) private readonly elementRef: ElementRef<HTMLElement>,
) {}

get tabs(): readonly HTMLElement[] {
return Array.from(
this.elementRef.nativeElement.querySelectorAll<HTMLElement>(`[tuiTab]`),
);
}

get activeElement(): HTMLElement | null {
return this.tabs[this.activeItemIndex] || null;
}

@HostListener(`${TUI_TAB_ACTIVATE}.stop`, [`$event.target`])
onActivate(element: HTMLElement): void {
const index = this.tabs.findIndex(tab => tab === element);

if (index === this.activeItemIndex) {
return;
}

this.activeItemIndexChange.emit(index);
this.activeItemIndex = index;
}

moveFocus(current: HTMLElement, step: number): void {
const {tabs} = this;

tuiMoveFocus(tabs.indexOf(current), tabs, step);
}

ngAfterViewChecked(): void {
const {tabs, activeElement} = this;

tabs.forEach(nativeElement => {
const active = nativeElement === activeElement;

nativeElement.classList.toggle(`_active`, active);
nativeElement.setAttribute(`tabIndex`, active ? `0` : `-1`);
});
}
}
8 changes: 7 additions & 1 deletion projects/kit/components/tabs/tabs.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,34 @@ import {TuiHostedDropdownModule, TuiSvgModule} from '@taiga-ui/core';
import {PolymorpheusModule} from '@tinkoff/ng-polymorpheus';

import {TuiTabComponent} from './tab/tab.component';
import {TuiTabsDirective} from './tabs.directive';
import {TuiTabsComponent} from './tabs/tabs.component';
import {TuiTabsVerticalComponent} from './tabs-vertical/tabs-vertical.component';
import {TuiTabsWithMoreComponent} from './tabs-with-more/tabs-with-more.component';
import {TuiUnderlineComponent} from './underline/underline.component';

@NgModule({
imports: [
CommonModule,
PolymorpheusModule,
TuiHostedDropdownModule,
TuiSvgModule,
TuiFocusableModule,
PolymorpheusModule,
TuiItemModule,
],
declarations: [
TuiTabsWithMoreComponent,
TuiTabsComponent,
TuiTabsDirective,
TuiTabsVerticalComponent,
TuiTabComponent,
TuiUnderlineComponent,
],
exports: [
TuiTabsWithMoreComponent,
TuiTabsComponent,
TuiTabsDirective,
TuiTabsVerticalComponent,
TuiTabComponent,
TuiItemDirective,
],
Expand Down
Loading

0 comments on commit a0513c8

Please sign in to comment.