diff --git a/projects/demo/src/modules/app/app.routes.ts b/projects/demo/src/modules/app/app.routes.ts
index c9857721a74e..92f927d4f858 100644
--- a/projects/demo/src/modules/app/app.routes.ts
+++ b/projects/demo/src/modules/app/app.routes.ts
@@ -361,6 +361,15 @@ export const ROUTES: Routes = [
title: 'ButtonClose',
},
},
+ {
+ path: 'experimental/button-group',
+ loadChildren: async () =>
+ (await import('../experimental/button-group/button-group.module'))
+ .ExampleTuiButtonGroupModule,
+ data: {
+ title: 'ButtonGroup',
+ },
+ },
{
path: 'experimental/cell',
loadChildren: async () =>
diff --git a/projects/demo/src/modules/app/pages.ts b/projects/demo/src/modules/app/pages.ts
index 0d6fd8f86cd9..766ec73c11f1 100644
--- a/projects/demo/src/modules/app/pages.ts
+++ b/projects/demo/src/modules/app/pages.ts
@@ -916,6 +916,12 @@ export const pages: TuiDocPages = [
keywords: 'кнопка, button, close, закрыть',
route: '/experimental/button-close',
},
+ {
+ section: 'Experimental',
+ title: 'ButtonGroup',
+ keywords: 'кнопка, button, group, группа',
+ route: '/experimental/button-group',
+ },
],
},
{
diff --git a/projects/demo/src/modules/experimental/button-group/button-group.component.ts b/projects/demo/src/modules/experimental/button-group/button-group.component.ts
new file mode 100644
index 000000000000..45b46f5f3d2a
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/button-group.component.ts
@@ -0,0 +1,31 @@
+import {Component} from '@angular/core';
+import {changeDetection} from '@demo/emulate/change-detection';
+import {TuiDocExample, TuiRawLoaderContent} from '@taiga-ui/addon-doc';
+
+@Component({
+ selector: 'example-button-group-card',
+ templateUrl: './button-group.template.html',
+ changeDetection,
+})
+export class ExampleTuiButtonGroupComponent {
+ readonly exampleModule: TuiRawLoaderContent = import(
+ './examples/import/import-module.md?raw'
+ );
+
+ readonly exampleHtml: TuiRawLoaderContent = import(
+ './examples/import/insert-template.md?raw'
+ );
+
+ readonly example1: TuiDocExample = {
+ HTML: import('./examples/1/index.html?raw'),
+ };
+
+ readonly example2: TuiDocExample = {
+ HTML: import('./examples/2/index.html?raw'),
+ };
+
+ readonly example3: TuiDocExample = {
+ HTML: import('./examples/3/index.html?raw'),
+ LESS: import('./examples/3/index.less?raw'),
+ };
+}
diff --git a/projects/demo/src/modules/experimental/button-group/button-group.module.ts b/projects/demo/src/modules/experimental/button-group/button-group.module.ts
new file mode 100644
index 000000000000..f7d3e8fcf544
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/button-group.module.ts
@@ -0,0 +1,33 @@
+import {CommonModule} from '@angular/common';
+import {NgModule} from '@angular/core';
+import {tuiGetDocModules} from '@taiga-ui/addon-doc';
+import {TuiNotificationModule} from '@taiga-ui/core';
+import {
+ TuiButtonGroupModule,
+ TuiIconModule,
+ TuiSurfaceModule,
+} from '@taiga-ui/experimental';
+
+import {ExampleTuiButtonGroupComponent} from './button-group.component';
+import {TuiButtonGroupExample1} from './examples/1';
+import {TuiButtonGroupExample2} from './examples/2';
+import {TuiButtonGroupExample3} from './examples/3';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ TuiIconModule,
+ TuiSurfaceModule,
+ TuiNotificationModule,
+ TuiButtonGroupModule,
+ tuiGetDocModules(ExampleTuiButtonGroupComponent),
+ ],
+ declarations: [
+ ExampleTuiButtonGroupComponent,
+ TuiButtonGroupExample1,
+ TuiButtonGroupExample2,
+ TuiButtonGroupExample3,
+ ],
+ exports: [ExampleTuiButtonGroupComponent],
+})
+export class ExampleTuiButtonGroupModule {}
diff --git a/projects/demo/src/modules/experimental/button-group/button-group.template.html b/projects/demo/src/modules/experimental/button-group/button-group.template.html
new file mode 100644
index 000000000000..0e89a2f09802
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/button-group.template.html
@@ -0,0 +1,59 @@
+
+
+
+ This code is
+ experimental
+ and is a subject to change. Expect final solution to be shipped in the next major version
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
Import module:
+
+
+
+
+ -
+
Add to the template:
+
+
+
+
+
+
diff --git a/projects/demo/src/modules/experimental/button-group/examples/1/index.html b/projects/demo/src/modules/experimental/button-group/examples/1/index.html
new file mode 100644
index 000000000000..a62f550370fd
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/1/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/demo/src/modules/experimental/button-group/examples/1/index.less b/projects/demo/src/modules/experimental/button-group/examples/1/index.less
new file mode 100644
index 000000000000..1aae53ea422f
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/1/index.less
@@ -0,0 +1,12 @@
+@import '@taiga-ui/core/styles/taiga-ui-local';
+
+:host {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ width: 21.5625rem;
+
+ @media @tui-mobile {
+ width: 100%;
+ }
+}
diff --git a/projects/demo/src/modules/experimental/button-group/examples/1/index.ts b/projects/demo/src/modules/experimental/button-group/examples/1/index.ts
new file mode 100644
index 000000000000..3cefd7843236
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/1/index.ts
@@ -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-button-group-example-1',
+ templateUrl: './index.html',
+ styleUrls: ['./index.less'],
+ encapsulation,
+ changeDetection,
+})
+export class TuiButtonGroupExample1 {}
diff --git a/projects/demo/src/modules/experimental/button-group/examples/2/index.html b/projects/demo/src/modules/experimental/button-group/examples/2/index.html
new file mode 100644
index 000000000000..1e97a3cb5d3e
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/2/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/demo/src/modules/experimental/button-group/examples/2/index.less b/projects/demo/src/modules/experimental/button-group/examples/2/index.less
new file mode 100644
index 000000000000..1aae53ea422f
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/2/index.less
@@ -0,0 +1,12 @@
+@import '@taiga-ui/core/styles/taiga-ui-local';
+
+:host {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ width: 21.5625rem;
+
+ @media @tui-mobile {
+ width: 100%;
+ }
+}
diff --git a/projects/demo/src/modules/experimental/button-group/examples/2/index.ts b/projects/demo/src/modules/experimental/button-group/examples/2/index.ts
new file mode 100644
index 000000000000..8decc0e110e8
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/2/index.ts
@@ -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-button-group-example-2',
+ templateUrl: './index.html',
+ styleUrls: ['./index.less'],
+ encapsulation,
+ changeDetection,
+})
+export class TuiButtonGroupExample2 {}
diff --git a/projects/demo/src/modules/experimental/button-group/examples/3/index.html b/projects/demo/src/modules/experimental/button-group/examples/3/index.html
new file mode 100644
index 000000000000..5ceece8e95cd
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/3/index.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/projects/demo/src/modules/experimental/button-group/examples/3/index.less b/projects/demo/src/modules/experimental/button-group/examples/3/index.less
new file mode 100644
index 000000000000..78a3cab2a94e
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/3/index.less
@@ -0,0 +1,24 @@
+@import '@taiga-ui/core/styles/taiga-ui-local';
+
+:host {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ width: 21.5625rem;
+
+ @media @tui-mobile {
+ width: 100%;
+ }
+}
+
+[tuiSurface][data-surface='dark'] {
+ background: linear-gradient(334.83deg, #7d8ca0 0%, #647382 100%);
+
+ button {
+ color: #fff;
+
+ &:active {
+ --tui-clear: var(--tui-clear-inverse);
+ }
+ }
+}
diff --git a/projects/demo/src/modules/experimental/button-group/examples/3/index.ts b/projects/demo/src/modules/experimental/button-group/examples/3/index.ts
new file mode 100644
index 000000000000..052c8d9a8791
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/3/index.ts
@@ -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-button-group-example-3',
+ templateUrl: './index.html',
+ styleUrls: ['./index.less'],
+ encapsulation,
+ changeDetection,
+})
+export class TuiButtonGroupExample3 {}
diff --git a/projects/demo/src/modules/experimental/button-group/examples/import/import-module.md b/projects/demo/src/modules/experimental/button-group/examples/import/import-module.md
new file mode 100644
index 000000000000..99e96d5f8c09
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/import/import-module.md
@@ -0,0 +1,14 @@
+```ts
+import {NgModule} from '@angular/core';
+import {TuiButtonGroupModule} from '@taiga-ui/experimental';
+// ...
+
+@NgModule({
+ imports: [
+ // ...
+ TuiButtonModule,
+ TuiButtonGroupModule,
+ ],
+})
+export class MyModule {}
+```
diff --git a/projects/demo/src/modules/experimental/button-group/examples/import/insert-template.md b/projects/demo/src/modules/experimental/button-group/examples/import/insert-template.md
new file mode 100644
index 000000000000..167985df77d9
--- /dev/null
+++ b/projects/demo/src/modules/experimental/button-group/examples/import/insert-template.md
@@ -0,0 +1,11 @@
+```html
+
+
+
+```
diff --git a/projects/demo/used-icons.ts b/projects/demo/used-icons.ts
index 99021f8b7594..8ccf0a2845c8 100644
--- a/projects/demo/used-icons.ts
+++ b/projects/demo/used-icons.ts
@@ -101,6 +101,7 @@ export const TUI_USED_ICONS = [
'tuiIconLock',
'tuiIconUsers',
'tuiIconClock',
+ 'tuiIconArrowRightCircleLarge',
'tuiIconPlusSquareLarge',
'tuiIconTarget',
'tuiIconGooglePay',
diff --git a/projects/experimental/directives/button-group/button-group.component.ts b/projects/experimental/directives/button-group/button-group.component.ts
new file mode 100644
index 000000000000..d1385ce579b1
--- /dev/null
+++ b/projects/experimental/directives/button-group/button-group.component.ts
@@ -0,0 +1,12 @@
+import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/core';
+
+@Component({
+ template: '',
+ styleUrls: ['./button-group.style.less'],
+ encapsulation: ViewEncapsulation.None,
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ host: {
+ class: 'tui-button-group-styles',
+ },
+})
+export class TuiButtonGroupComponent {}
diff --git a/projects/experimental/directives/button-group/button-group.directive.ts b/projects/experimental/directives/button-group/button-group.directive.ts
new file mode 100644
index 000000000000..a9df64a25d55
--- /dev/null
+++ b/projects/experimental/directives/button-group/button-group.directive.ts
@@ -0,0 +1,15 @@
+import {Directive, Inject} from '@angular/core';
+import {TuiDirectiveStylesService} from '@taiga-ui/cdk';
+
+import {TuiButtonGroupComponent} from './button-group.component';
+
+@Directive({
+ selector: '[tuiButtonGroup]',
+})
+export class TuiButtonGroupDirective {
+ constructor(
+ @Inject(TuiDirectiveStylesService) directiveStyles: TuiDirectiveStylesService,
+ ) {
+ directiveStyles.addComponent(TuiButtonGroupComponent);
+ }
+}
diff --git a/projects/experimental/directives/button-group/button-group.module.ts b/projects/experimental/directives/button-group/button-group.module.ts
new file mode 100644
index 000000000000..b06322d26f43
--- /dev/null
+++ b/projects/experimental/directives/button-group/button-group.module.ts
@@ -0,0 +1,10 @@
+import {NgModule} from '@angular/core';
+
+import {TuiButtonGroupComponent} from './button-group.component';
+import {TuiButtonGroupDirective} from './button-group.directive';
+
+@NgModule({
+ declarations: [TuiButtonGroupDirective, TuiButtonGroupComponent],
+ exports: [TuiButtonGroupDirective],
+})
+export class TuiButtonGroupModule {}
diff --git a/projects/experimental/directives/button-group/button-group.style.less b/projects/experimental/directives/button-group/button-group.style.less
new file mode 100644
index 000000000000..9d8ad9b9604b
--- /dev/null
+++ b/projects/experimental/directives/button-group/button-group.style.less
@@ -0,0 +1,68 @@
+@import '@taiga-ui/core/styles/taiga-ui-local';
+
+[tuiButtonGroup] {
+ display: flex;
+ border-radius: var(--tui-radius-xl);
+ justify-content: center;
+ overflow: hidden;
+
+ > button,
+ > a {
+ .transition(background);
+ position: relative;
+ display: flex;
+ border: none;
+ outline: none;
+ background: transparent;
+ align-items: center;
+ flex: 1;
+ flex-direction: column;
+ padding: 1.125rem 0.25rem;
+ gap: 0.5rem;
+ font-size: var(--tui-font-text-s);
+ max-width: calc(50% - 1.75rem);
+ cursor: pointer;
+ color: var(--tui-link);
+ text-align: center;
+
+ &:active {
+ background: var(--tui-clear);
+ }
+
+ &:before,
+ &:after {
+ position: absolute;
+ top: 0;
+ background: inherit;
+ width: 1.75rem;
+ height: 100%;
+ }
+
+ &:first-child::before {
+ content: '';
+ left: -1.75rem;
+ }
+
+ &:last-child::after {
+ content: '';
+ right: -1.75rem;
+ }
+
+ tui-icon {
+ font-size: 1.75rem;
+ }
+ }
+
+ &:has(button:only-child) {
+ border-radius: var(--tui-radius-l);
+ }
+
+ > button:only-child,
+ > a:only-child {
+ width: 100%;
+ flex-direction: row;
+ font: var(--tui-font-text-l);
+ max-width: 100%;
+ justify-content: center;
+ }
+}
diff --git a/projects/experimental/directives/button-group/index.ts b/projects/experimental/directives/button-group/index.ts
new file mode 100644
index 000000000000..0c4cf1d35827
--- /dev/null
+++ b/projects/experimental/directives/button-group/index.ts
@@ -0,0 +1,3 @@
+export * from './button-group.component';
+export * from './button-group.directive';
+export * from './button-group.module';
diff --git a/projects/experimental/directives/button-group/ng-package.json b/projects/experimental/directives/button-group/ng-package.json
new file mode 100644
index 000000000000..bebf62dcb5e5
--- /dev/null
+++ b/projects/experimental/directives/button-group/ng-package.json
@@ -0,0 +1,5 @@
+{
+ "lib": {
+ "entryFile": "index.ts"
+ }
+}
diff --git a/projects/experimental/directives/index.ts b/projects/experimental/directives/index.ts
index 78a556d9b6c2..7d2856ccfe8b 100644
--- a/projects/experimental/directives/index.ts
+++ b/projects/experimental/directives/index.ts
@@ -1,5 +1,6 @@
export * from '@taiga-ui/experimental/directives/appearance';
export * from '@taiga-ui/experimental/directives/button-close';
+export * from '@taiga-ui/experimental/directives/button-group';
export * from '@taiga-ui/experimental/directives/button-vertical';
export * from '@taiga-ui/experimental/directives/card';
export * from '@taiga-ui/experimental/directives/cell';