diff --git a/packages/components-dev/tabs/module.ts b/packages/components-dev/tabs/module.ts index fb2093ed0..8a72ef877 100644 --- a/packages/components-dev/tabs/module.ts +++ b/packages/components-dev/tabs/module.ts @@ -3,15 +3,23 @@ import { KbqButtonModule } from '@koobiq/components/button'; import { KbqIconModule } from '@koobiq/components/icon'; import { KbqPopoverModule } from '@koobiq/components/popover'; import { KbqTabChangeEvent, KbqTabsModule } from '@koobiq/components/tabs'; -import { TabsVerticalExample } from 'packages/docs-examples/components/tabs'; +import { + TabsAddTabExample, + TabsAddTabVerticalExample, + TabsVerticalExample +} from 'packages/docs-examples/components/tabs'; import { DevThemeToggle } from '../theme-toggle'; @Component({ selector: 'dev-examples', - imports: [TabsVerticalExample], + imports: [TabsVerticalExample, TabsAddTabExample, TabsAddTabVerticalExample], template: `
+ +
+ +
`, changeDetection: ChangeDetectionStrategy.OnPush }) diff --git a/packages/components/tabs/tabs.en.md b/packages/components/tabs/tabs.en.md index 899895396..298aba1da 100644 --- a/packages/components/tabs/tabs.en.md +++ b/packages/components/tabs/tabs.en.md @@ -64,6 +64,16 @@ Unlike `KbqTabGroup`, `KbqTabNavBar` is used for navigation between application +### Creating tabs + +Create and delete tabs like in a browser. The create button is located at the end of the list of tabs. When there is scrolling, the button moves to the right to remain visible. + + + +Vertical tabs + + + ### Hot keys | Key | Action | diff --git a/packages/components/tabs/tabs.ru.md b/packages/components/tabs/tabs.ru.md index 0747c798d..c86847254 100644 --- a/packages/components/tabs/tabs.ru.md +++ b/packages/components/tabs/tabs.ru.md @@ -64,6 +64,16 @@ +### Создание вкладок + +Создание и удаление как в браузере. Кнопка создания располагается в конце списка вкладок. Когда есть прокрутка, то кнопка перемещается направо, чтобы всегда оставаться видимой. + + + +Вертикальные вкладки + + + ### Работа с клавиатурой | Клавиша | Действие | diff --git a/packages/docs-examples/components/tabs/index.ts b/packages/docs-examples/components/tabs/index.ts index b23db0b57..bdafd5f69 100644 --- a/packages/docs-examples/components/tabs/index.ts +++ b/packages/docs-examples/components/tabs/index.ts @@ -2,6 +2,8 @@ import { NgModule } from '@angular/core'; import { TabsActionbarExample } from './tabs-actionbar/tabs-actionbar-example'; import { TabsActiveTabIdExample } from './tabs-active-tab-id/tabs-active-tab-id-example'; import { TabsActiveTabIndexExample } from './tabs-active-tab-index/tabs-active-tab-index-example'; +import { TabsAddTabVerticalExample } from './tabs-add-tab-vertical/tabs-add-tab-vertical-example'; +import { TabsAddTabExample } from './tabs-add-tab/tabs-add-tab-example'; import { TabsCustomLabelExample } from './tabs-custom-label/tabs-custom-label-example'; import { TabsDisabledExample } from './tabs-disabled/tabs-disabled-example'; import { TabsEmptyLabelExample } from './tabs-empty-label/tabs-empty-label-example'; @@ -18,6 +20,8 @@ export { TabsActionbarExample, TabsActiveTabIdExample, TabsActiveTabIndexExample, + TabsAddTabExample, + TabsAddTabVerticalExample, TabsCustomLabelExample, TabsDisabledExample, TabsEmptyLabelExample, @@ -35,6 +39,8 @@ const EXAMPLES = [ TabsActiveTabIdExample, TabsActiveTabIndexExample, TabsActionbarExample, + TabsAddTabExample, + TabsAddTabVerticalExample, TabsCustomLabelExample, TabsDisabledExample, TabsEmptyLabelExample, diff --git a/packages/docs-examples/components/tabs/tabs-add-tab-vertical/tabs-add-tab-vertical-example.css b/packages/docs-examples/components/tabs/tabs-add-tab-vertical/tabs-add-tab-vertical-example.css new file mode 100644 index 000000000..c44556b5a --- /dev/null +++ b/packages/docs-examples/components/tabs/tabs-add-tab-vertical/tabs-add-tab-vertical-example.css @@ -0,0 +1,37 @@ +:host { + display: flex; + width: 100%; + max-width: 100%; + height: 250px; + --tab-nav-selected: var(--kbq-tabs-tab-item-filled-on-background-states-selected-background); +} + +.example-tab-nav-bar { + width: 240px; +} + +.example-tab-link { + display: inline-block; + text-align: left; + overflow: hidden; + text-overflow: ellipsis; +} + +.example-tab-close { + position: absolute; + right: calc(var(--kbq-tabs-size-tab-item-padding-horizontal) - var(--kbq-tabs-size-tab-item-focus-outline-width)); + top: 0; + bottom: 0; + width: 32px; + display: flex; + align-items: center; + justify-content: flex-end; + background: linear-gradient(var(--tab-nav-selected), var(--tab-nav-selected)), var(--kbq-background-bg); + mask-image: linear-gradient(to right, transparent 0%, black 50%); +} + +.example-tabs-add-tab-vertical__content { + flex: 1; + padding: var(--kbq-size-m); + overflow: auto; +} diff --git a/packages/docs-examples/components/tabs/tabs-add-tab-vertical/tabs-add-tab-vertical-example.ts b/packages/docs-examples/components/tabs/tabs-add-tab-vertical/tabs-add-tab-vertical-example.ts new file mode 100644 index 000000000..d7eeefc86 --- /dev/null +++ b/packages/docs-examples/components/tabs/tabs-add-tab-vertical/tabs-add-tab-vertical-example.ts @@ -0,0 +1,61 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { KbqButtonModule } from '@koobiq/components/button'; +import { KbqIconModule } from '@koobiq/components/icon'; +import { KbqTabsModule } from '@koobiq/components/tabs'; + +/** + * @title Tabs add tab vertical + */ +@Component({ + selector: 'tabs-add-tab-vertical-example', + imports: [KbqTabsModule, KbqButtonModule, KbqIconModule], + template: ` + + +
+ Content for {{ activeTab }} +
+ `, + styleUrls: ['./tabs-add-tab-vertical-example.css'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class TabsAddTabVerticalExample { + protected tabs = ['BruteForce', 'Complex Attack', 'DDoS', 'HIPS alert']; + protected activeTab = this.tabs[0]; + + protected addTab(): void { + const newTab = `Tab ${this.tabs.length + 1}`; + + this.tabs = [...this.tabs, newTab]; + this.activeTab = newTab; + } + + protected removeTab(tab: string, event: MouseEvent): void { + event.stopPropagation(); + const index = this.tabs.indexOf(tab); + + this.tabs = this.tabs.filter((t) => t !== tab); + + if (this.tabs.length > 0) { + this.activeTab = this.tabs[Math.max(0, index - 1)]; + } + } +} diff --git a/packages/docs-examples/components/tabs/tabs-add-tab/tabs-add-tab-example.css b/packages/docs-examples/components/tabs/tabs-add-tab/tabs-add-tab-example.css new file mode 100644 index 000000000..23d95e8fc --- /dev/null +++ b/packages/docs-examples/components/tabs/tabs-add-tab/tabs-add-tab-example.css @@ -0,0 +1,23 @@ +:host { + display: flex; + align-items: center; + gap: var(--kbq-size-l); + --tab-nav-selected: var(--kbq-tabs-tab-item-filled-on-background-states-selected-background); +} + +.example-tab-nav-bar { + overflow: hidden; +} + +.example-tab-close { + position: absolute; + right: calc(var(--kbq-tabs-size-tab-item-padding-horizontal) - var(--kbq-tabs-size-tab-item-focus-outline-width)); + top: 0; + bottom: 0; + width: 32px; + display: flex; + align-items: center; + justify-content: flex-end; + background: linear-gradient(var(--tab-nav-selected), var(--tab-nav-selected)), var(--kbq-background-bg); + mask-image: linear-gradient(to right, transparent 0%, black 50%); +} diff --git a/packages/docs-examples/components/tabs/tabs-add-tab/tabs-add-tab-example.ts b/packages/docs-examples/components/tabs/tabs-add-tab/tabs-add-tab-example.ts new file mode 100644 index 000000000..ccbb4f675 --- /dev/null +++ b/packages/docs-examples/components/tabs/tabs-add-tab/tabs-add-tab-example.ts @@ -0,0 +1,57 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { KbqButtonModule } from '@koobiq/components/button'; +import { KbqIconModule } from '@koobiq/components/icon'; +import { KbqTabsModule } from '@koobiq/components/tabs'; + +/** + * @title Tabs add tab + */ +@Component({ + selector: 'tabs-add-tab-example', + imports: [KbqTabsModule, KbqButtonModule, KbqIconModule], + template: ` + + + `, + styleUrls: ['./tabs-add-tab-example.css'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class TabsAddTabExample { + protected tabs = ['BruteForce', 'Complex Attack', 'DDoS', 'HIPS alert']; + protected activeTab = this.tabs[0]; + + protected addTab(): void { + const newTab = `Tab ${this.tabs.length + 1}`; + + this.tabs = [...this.tabs, newTab]; + this.activeTab = newTab; + } + + protected removeTab(tab: string, event: MouseEvent): void { + event.stopPropagation(); + const index = this.tabs.indexOf(tab); + + this.tabs = this.tabs.filter((t) => t !== tab); + + if (this.tabs.length > 0) { + this.activeTab = this.tabs[Math.max(0, index - 1)]; + } + } +}