From ded734c57617ebe9b23005382dd56185519dba36 Mon Sep 17 00:00:00 2001
From: Vladimir Potekhin <46284632+vladimirpotekhin@users.noreply.github.com>
Date: Mon, 2 Oct 2023 15:47:15 +0300
Subject: [PATCH] feat(experimental): `BadgedContent` add new component (#5498)
---
projects/demo/src/modules/app/app.routes.ts | 9 ++
projects/demo/src/modules/app/pages.ts | 6 ++
.../badged-content.component.ts | 33 +++++++
.../badged-content/badged-content.module.ts | 46 +++++++++
.../badged-content.template.html | 95 +++++++++++++++++++
.../badged-content/examples/1/index.html | 59 ++++++++++++
.../badged-content/examples/1/index.less | 4 +
.../badged-content/examples/1/index.ts | 12 +++
.../badged-content/examples/2/index.html | 57 +++++++++++
.../badged-content/examples/2/index.less | 4 +
.../badged-content/examples/2/index.ts | 12 +++
.../badged-content/examples/3/index.html | 19 ++++
.../badged-content/examples/3/index.less | 8 ++
.../badged-content/examples/3/index.ts | 12 +++
.../examples/import/import-module.md | 13 +++
.../examples/import/insert-template.md | 7 ++
.../components/badge/badge.style.less | 3 +-
.../badged-content.component.ts | 9 ++
.../badged-content.directive.ts | 9 ++
.../badged-content/badged-content.module.ts | 13 +++
.../badged-content/badged-content.style.less | 34 +++++++
.../badged-content.template.html | 25 +++++
.../components/badged-content/index.ts | 3 +
.../components/badged-content/ng-package.json | 8 ++
projects/experimental/components/index.ts | 1 +
25 files changed, 499 insertions(+), 2 deletions(-)
create mode 100644 projects/demo/src/modules/experimental/badged-content/badged-content.component.ts
create mode 100644 projects/demo/src/modules/experimental/badged-content/badged-content.module.ts
create mode 100644 projects/demo/src/modules/experimental/badged-content/badged-content.template.html
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/1/index.html
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/1/index.less
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/1/index.ts
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/2/index.html
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/2/index.less
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/2/index.ts
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/3/index.html
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/3/index.less
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/3/index.ts
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/import/import-module.md
create mode 100644 projects/demo/src/modules/experimental/badged-content/examples/import/insert-template.md
create mode 100644 projects/experimental/components/badged-content/badged-content.component.ts
create mode 100644 projects/experimental/components/badged-content/badged-content.directive.ts
create mode 100644 projects/experimental/components/badged-content/badged-content.module.ts
create mode 100644 projects/experimental/components/badged-content/badged-content.style.less
create mode 100644 projects/experimental/components/badged-content/badged-content.template.html
create mode 100644 projects/experimental/components/badged-content/index.ts
create mode 100644 projects/experimental/components/badged-content/ng-package.json
diff --git a/projects/demo/src/modules/app/app.routes.ts b/projects/demo/src/modules/app/app.routes.ts
index 5f6b2880bfcf..74e49718ee45 100644
--- a/projects/demo/src/modules/app/app.routes.ts
+++ b/projects/demo/src/modules/app/app.routes.ts
@@ -223,6 +223,15 @@ export const ROUTES: Routes = [
title: `BadgeAlert`,
},
},
+ {
+ path: `experimental/badged-content`,
+ loadChildren: async () =>
+ (await import(`../experimental/badged-content/badged-content.module`))
+ .ExampleTuiBadgedContentModule,
+ data: {
+ title: `BadgedContent`,
+ },
+ },
{
path: `experimental/button`,
loadChildren: async () =>
diff --git a/projects/demo/src/modules/app/pages.ts b/projects/demo/src/modules/app/pages.ts
index 6657c52d9c00..17faa283e535 100644
--- a/projects/demo/src/modules/app/pages.ts
+++ b/projects/demo/src/modules/app/pages.ts
@@ -839,6 +839,12 @@ export const pages: TuiDocPages = [
keywords: `бэдж, бейдж, circle, круг, badge, alert, нотификация`,
route: `/experimental/badge-alert`,
},
+ {
+ section: `Experimental`,
+ title: `BadgedContent`,
+ keywords: `бэдж, бейдж, circle, овал, круг, badge, нотификация`,
+ route: `/experimental/badged-content`,
+ },
],
},
{
diff --git a/projects/demo/src/modules/experimental/badged-content/badged-content.component.ts b/projects/demo/src/modules/experimental/badged-content/badged-content.component.ts
new file mode 100644
index 000000000000..ef6ccda3db3c
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/badged-content.component.ts
@@ -0,0 +1,33 @@
+import {Component} from '@angular/core';
+import {changeDetection} from '@demo/emulate/change-detection';
+import {RawLoaderContent, TuiDocExample} from '@taiga-ui/addon-doc';
+
+@Component({
+ selector: 'example-badged-content',
+ templateUrl: './badged-content.template.html',
+ changeDetection,
+})
+export class ExampleTuiBadgeAlertComponent {
+ readonly exampleModule: RawLoaderContent = import(
+ './examples/import/import-module.md?raw'
+ );
+
+ readonly exampleHtml: RawLoaderContent = 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'),
+ };
+
+ radiusVariants = ['0.75rem', '50%'];
+ radius = this.radiusVariants[0];
+}
diff --git a/projects/demo/src/modules/experimental/badged-content/badged-content.module.ts b/projects/demo/src/modules/experimental/badged-content/badged-content.module.ts
new file mode 100644
index 000000000000..8b958d4ac044
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/badged-content.module.ts
@@ -0,0 +1,46 @@
+import {CommonModule} from '@angular/common';
+import {NgModule} from '@angular/core';
+import {RouterModule} from '@angular/router';
+import {TuiAddonDocModule, tuiGenerateRoutes} from '@taiga-ui/addon-doc';
+import {TuiPlatformModule} from '@taiga-ui/cdk';
+import {TuiNotificationModule, TuiSvgModule} from '@taiga-ui/core';
+import {
+ TuiAvatarModule,
+ TuiBadgeAlertModule,
+ TuiBadgedContentModule,
+ TuiBadgeModule,
+ TuiButtonModule,
+ TuiFallbackSrcModule,
+} from '@taiga-ui/experimental';
+import {TuiInputModule} from '@taiga-ui/kit';
+
+import {ExampleTuiBadgeAlertComponent} from './badged-content.component';
+import {TuiBadgedContentExample1} from './examples/1';
+import {TuiBadgedContentExample2} from './examples/2';
+import {TuiBadgedContentExample3} from './examples/3';
+
+@NgModule({
+ imports: [
+ CommonModule,
+ TuiBadgeAlertModule,
+ TuiSvgModule,
+ TuiBadgeModule,
+ TuiBadgedContentModule,
+ TuiAvatarModule,
+ TuiFallbackSrcModule,
+ TuiInputModule,
+ TuiButtonModule,
+ TuiAddonDocModule,
+ TuiNotificationModule,
+ RouterModule.forChild(tuiGenerateRoutes(ExampleTuiBadgeAlertComponent)),
+ TuiPlatformModule,
+ ],
+ declarations: [
+ ExampleTuiBadgeAlertComponent,
+ TuiBadgedContentExample1,
+ TuiBadgedContentExample2,
+ TuiBadgedContentExample3,
+ ],
+ exports: [ExampleTuiBadgeAlertComponent],
+})
+export class ExampleTuiBadgedContentModule {}
diff --git a/projects/demo/src/modules/experimental/badged-content/badged-content.template.html b/projects/demo/src/modules/experimental/badged-content/badged-content.template.html
new file mode 100644
index 000000000000..887d7fd516d2
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/badged-content.template.html
@@ -0,0 +1,95 @@
+
+
+
+ This code is
+ experimental
+ and is a subject to change. Expect final solution to be shipped in the next major version
+
+
+ BadgedContent is a wrapper for other components to add badges and notifications to them.
+
+
+
+
+
+
+
+
+ The wrapped element is assumed to have 12px border-radius. If it is different, override the
+ --tui-radius
+ variable with actual value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+ Border radius
+
+
+
+
+
+
+ -
+
Import into a module
+
+
+
+
+ -
+
Add to the template:
+
+
+
+
+
+
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/1/index.html b/projects/demo/src/modules/experimental/badged-content/examples/1/index.html
new file mode 100644
index 000000000000..fce9b332cd81
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/examples/1/index.html
@@ -0,0 +1,59 @@
+
+
+ 99
+
+
+
+
+
+
+
+ 120
+
+
+
+
+
+
+
+
+
+
+
+
+ 99
+
+
+
+
+
+
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/1/index.less b/projects/demo/src/modules/experimental/badged-content/examples/1/index.less
new file mode 100644
index 000000000000..e8c357f08e0d
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/examples/1/index.less
@@ -0,0 +1,4 @@
+:host {
+ display: flex;
+ gap: 1rem;
+}
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/1/index.ts b/projects/demo/src/modules/experimental/badged-content/examples/1/index.ts
new file mode 100644
index 000000000000..3d303b0e5b0b
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/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-badged-content-example-1',
+ templateUrl: './index.html',
+ styleUrls: ['./index.less'],
+ changeDetection,
+ encapsulation,
+})
+export class TuiBadgedContentExample1 {}
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/2/index.html b/projects/demo/src/modules/experimental/badged-content/examples/2/index.html
new file mode 100644
index 000000000000..b85d73ab2e96
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/examples/2/index.html
@@ -0,0 +1,57 @@
+
+
+ 8
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Taiga
+
+
+
+
+
+
+ 99
+
+
+
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/2/index.less b/projects/demo/src/modules/experimental/badged-content/examples/2/index.less
new file mode 100644
index 000000000000..e8c357f08e0d
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/examples/2/index.less
@@ -0,0 +1,4 @@
+:host {
+ display: flex;
+ gap: 1rem;
+}
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/2/index.ts b/projects/demo/src/modules/experimental/badged-content/examples/2/index.ts
new file mode 100644
index 000000000000..7c64262961ff
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/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-badged-content-example-2',
+ templateUrl: './index.html',
+ styleUrls: ['./index.less'],
+ changeDetection,
+ encapsulation,
+})
+export class TuiBadgedContentExample2 {}
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/3/index.html b/projects/demo/src/modules/experimental/badged-content/examples/3/index.html
new file mode 100644
index 000000000000..0d8ec7dd9774
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/examples/3/index.html
@@ -0,0 +1,19 @@
+
+
+ Input text
+
+
+
+
+
+
+
+
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/3/index.less b/projects/demo/src/modules/experimental/badged-content/examples/3/index.less
new file mode 100644
index 000000000000..588ea4ecc09b
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/examples/3/index.less
@@ -0,0 +1,8 @@
+:host {
+ display: flex;
+ gap: 1rem;
+}
+
+tui-input {
+ min-width: 10rem;
+}
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/3/index.ts b/projects/demo/src/modules/experimental/badged-content/examples/3/index.ts
new file mode 100644
index 000000000000..e53ede1886fb
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/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-badged-content-example-3',
+ templateUrl: './index.html',
+ styleUrls: ['./index.less'],
+ changeDetection,
+ encapsulation,
+})
+export class TuiBadgedContentExample3 {}
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/import/import-module.md b/projects/demo/src/modules/experimental/badged-content/examples/import/import-module.md
new file mode 100644
index 000000000000..df5e4f5aa31f
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/examples/import/import-module.md
@@ -0,0 +1,13 @@
+```ts
+import {NgModule} from '@angular/core';
+import {TuiBadgedContentModule} from '@taiga-ui/experimental';
+// ...
+
+@NgModule({
+ imports: [
+ // ...
+ TuiBadgedContentModule,
+ ],
+})
+export class MyModule {}
+```
diff --git a/projects/demo/src/modules/experimental/badged-content/examples/import/insert-template.md b/projects/demo/src/modules/experimental/badged-content/examples/import/insert-template.md
new file mode 100644
index 000000000000..6bbf682f3dc1
--- /dev/null
+++ b/projects/demo/src/modules/experimental/badged-content/examples/import/insert-template.md
@@ -0,0 +1,7 @@
+```html
+
+ 1
+
+ 1
+
+```
diff --git a/projects/experimental/components/badge/badge.style.less b/projects/experimental/components/badge/badge.style.less
index 9f71e006909a..8b9872bc9b54 100644
--- a/projects/experimental/components/badge/badge.style.less
+++ b/projects/experimental/components/badge/badge.style.less
@@ -1,8 +1,6 @@
@import 'taiga-ui-local';
:host {
- .transition(background);
-
--left-content-color: currentColor;
position: relative;
display: inline-flex;
@@ -221,6 +219,7 @@
}
&._hoverable {
+ .transition(background);
cursor: pointer;
}
diff --git a/projects/experimental/components/badged-content/badged-content.component.ts b/projects/experimental/components/badged-content/badged-content.component.ts
new file mode 100644
index 000000000000..d006dc1c55c2
--- /dev/null
+++ b/projects/experimental/components/badged-content/badged-content.component.ts
@@ -0,0 +1,9 @@
+import {ChangeDetectionStrategy, Component} from '@angular/core';
+
+@Component({
+ selector: 'tui-badged-content',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ templateUrl: './badged-content.template.html',
+ styleUrls: ['./badged-content.style.less'],
+})
+export class TuiBadgedContentComponent {}
diff --git a/projects/experimental/components/badged-content/badged-content.directive.ts b/projects/experimental/components/badged-content/badged-content.directive.ts
new file mode 100644
index 000000000000..ebf39dc8b4c0
--- /dev/null
+++ b/projects/experimental/components/badged-content/badged-content.directive.ts
@@ -0,0 +1,9 @@
+import {Directive, Input} from '@angular/core';
+
+@Directive({
+ selector: '[tuiSlot]',
+})
+export class TuiBadgedContentDirective {
+ @Input()
+ tuiSlot: string | 'bottom' | 'top' = 'top';
+}
diff --git a/projects/experimental/components/badged-content/badged-content.module.ts b/projects/experimental/components/badged-content/badged-content.module.ts
new file mode 100644
index 000000000000..68d6686b2652
--- /dev/null
+++ b/projects/experimental/components/badged-content/badged-content.module.ts
@@ -0,0 +1,13 @@
+import {CommonModule} from '@angular/common';
+import {NgModule} from '@angular/core';
+import {TuiResizeModule} from '@taiga-ui/cdk';
+
+import {TuiBadgedContentComponent} from './badged-content.component';
+import {TuiBadgedContentDirective} from './badged-content.directive';
+
+@NgModule({
+ imports: [CommonModule, TuiResizeModule],
+ declarations: [TuiBadgedContentComponent, TuiBadgedContentDirective],
+ exports: [TuiBadgedContentComponent, TuiBadgedContentDirective],
+})
+export class TuiBadgedContentModule {}
diff --git a/projects/experimental/components/badged-content/badged-content.style.less b/projects/experimental/components/badged-content/badged-content.style.less
new file mode 100644
index 000000000000..46d0ca6751c7
--- /dev/null
+++ b/projects/experimental/components/badged-content/badged-content.style.less
@@ -0,0 +1,34 @@
+@import 'taiga-ui-local';
+
+:host {
+ --tui-radius: var(--tui-radius-l);
+ --t-badge-height: 0;
+ --t-corner-offset: calc((var(--tui-radius) * 1.4142 - var(--tui-radius)) * 1 / 1.4142);
+ position: relative;
+ display: inline-block;
+ height: fit-content;
+ width: max-content;
+ color: var(--tui-base-01);
+}
+
+.t-badge {
+ --t-offset: calc(var(--t-badge-height) * -0.5 + var(--t-corner-offset));
+ position: absolute;
+ display: flex;
+
+ &_top {
+ top: var(--t-offset);
+ right: var(--t-offset);
+ }
+
+ &_bottom {
+ bottom: var(--t-offset);
+ right: var(--t-offset);
+ }
+}
+
+.t-border:not(:empty) {
+ display: flex;
+ border-radius: 6rem;
+ box-shadow: 0 0 0 1px currentColor;
+}
diff --git a/projects/experimental/components/badged-content/badged-content.template.html b/projects/experimental/components/badged-content/badged-content.template.html
new file mode 100644
index 000000000000..eb99e26d27e9
--- /dev/null
+++ b/projects/experimental/components/badged-content/badged-content.template.html
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/projects/experimental/components/badged-content/index.ts b/projects/experimental/components/badged-content/index.ts
new file mode 100644
index 000000000000..bab87f01b1fd
--- /dev/null
+++ b/projects/experimental/components/badged-content/index.ts
@@ -0,0 +1,3 @@
+export * from './badged-content.component';
+export * from './badged-content.directive';
+export * from './badged-content.module';
diff --git a/projects/experimental/components/badged-content/ng-package.json b/projects/experimental/components/badged-content/ng-package.json
new file mode 100644
index 000000000000..bab5ebcdb74a
--- /dev/null
+++ b/projects/experimental/components/badged-content/ng-package.json
@@ -0,0 +1,8 @@
+{
+ "lib": {
+ "entryFile": "index.ts",
+ "styleIncludePaths": [
+ "../../../core/styles"
+ ]
+ }
+}
diff --git a/projects/experimental/components/index.ts b/projects/experimental/components/index.ts
index 102734aaf4a7..622d1f31769d 100644
--- a/projects/experimental/components/index.ts
+++ b/projects/experimental/components/index.ts
@@ -2,5 +2,6 @@ export * from '@taiga-ui/experimental/components/avatar';
export * from '@taiga-ui/experimental/components/avatar-stack';
export * from '@taiga-ui/experimental/components/badge';
export * from '@taiga-ui/experimental/components/badge-alert';
+export * from '@taiga-ui/experimental/components/badged-content';
export * from '@taiga-ui/experimental/components/button';
export * from '@taiga-ui/experimental/components/sensitive';