From 2fc8ad308dc5ddbcae29f3028f47bdd48f261128 Mon Sep 17 00:00:00 2001 From: Alex Inkin Date: Wed, 31 Jul 2024 16:00:30 +0400 Subject: [PATCH] refactor(core): `Notification` simplify to directive (#8168) Co-authored-by: taiga-family-bot --- .../components/axes/axes.style.less | 10 +- projects/addon-doc/components/code/index.less | 1 - .../components/example/example.component.ts | 2 +- .../components/example/example.style.less | 4 + .../components/main/main.component.ts | 4 +- .../addon-doc/components/main/main.style.less | 4 + .../steps/constants/identifiers-to-replace.ts | 4 - .../ng-update/v4/steps/constants/types.ts | 6 + .../core/components/alert/alert.component.ts | 70 +++-- .../core/components/alert/alert.interfaces.ts | 9 +- .../core/components/alert/alert.style.less | 37 +-- .../core/components/alert/alert.template.html | 34 +-- .../core/components/alert/alert.tokens.ts | 2 +- .../core/components/notification/index.ts | 2 +- .../notification/notification.component.ts | 63 ----- .../notification/notification.directive.ts | 80 ++++++ .../notification/notification.options.ts | 21 +- .../notification/notification.style.less | 126 --------- .../notification/notification.template.html | 29 --- .../test/notification.component.spec.ts | 138 ---------- .../components/textfield/textfield.style.less | 5 + projects/core/styles/components/icons.less | 8 +- .../core/styles/components/notification.less | 123 +++++++++ .../core/styles/theme/appearance/icon.less | 1 - .../core/styles/theme/appearance/status.less | 25 +- .../kit/notification/notification.spec.ts | 39 --- projects/demo/src/modules/app/app.config.ts | 4 +- .../src/modules/app/home/home.template.html | 26 +- .../src/modules/app/styles-info/index.html | 26 +- .../components/alert/examples/2/index.html | 4 - .../components/alert/examples/2/index.ts | 4 +- .../components/alert/examples/3/index.ts | 2 +- .../components/alert/examples/4/index.ts | 17 +- .../components/alert/examples/5/index.ts | 8 +- .../components/alert/examples/6/index.html | 5 +- .../alert/examples/import/define-options.md | 2 +- .../src/modules/components/alert/index.html | 8 +- .../src/modules/components/alert/index.ts | 13 +- .../components/axes/examples/1/index.ts | 2 +- .../components/axes/examples/3/index.html | 1 - .../src/modules/components/axes/index.html | 11 +- .../demo/src/modules/components/axes/index.ts | 6 +- .../components/bar-chart/examples/1/index.ts | 2 +- .../components/bar-chart/examples/2/index.ts | 2 +- .../modules/components/bar-chart/index.html | 20 +- .../components/cell/examples/7/index.html | 6 +- .../components/cell/examples/7/index.ts | 3 +- .../modules/components/checkbox/index.html | 8 +- .../components/chip/examples/2/index.ts | 3 +- .../components/chip/examples/3/index.ts | 2 +- .../modules/components/combo-box/index.html | 34 ++- .../src/modules/components/confirm/index.html | 20 +- .../modules/components/data-list/index.html | 16 +- .../src/modules/components/dialog/index.html | 19 +- .../icons-group/icons-group.component.ts | 2 +- .../modules/components/input-color/index.html | 24 +- .../modules/components/input-copy/index.html | 12 +- .../components/input-date-range/index.html | 12 +- .../components/input-date-time/index.html | 12 +- .../input-date/examples/4/index.html | 12 +- .../modules/components/input-files/index.html | 2 +- .../components/input-month-range/index.html | 12 +- .../modules/components/input-month/index.html | 12 +- .../components/input-number/index.html | 12 +- .../components/input-password/index.html | 12 +- .../input-phone-international/index.html | 74 +++--- .../modules/components/input-phone/index.html | 12 +- .../modules/components/input-range/index.html | 8 +- .../components/input-slider/index.html | 8 +- .../modules/components/input-year/index.html | 12 +- .../components/input/examples/10/index.html | 14 +- .../src/modules/components/input/index.html | 40 +-- .../src/modules/components/island/index.html | 20 +- .../line-clamp/examples/1/index.html | 8 +- .../line-days-chart/examples/1/index.html | 2 +- .../line-days-chart/examples/1/index.ts | 12 +- .../line-days-chart/examples/2/index.html | 8 +- .../line-days-chart/examples/2/index.ts | 15 +- .../components/line-days-chart/index.ts | 2 +- .../modules/components/navigation/index.html | 6 - .../notification/examples/1/index.html | 65 +++-- .../notification/examples/1/index.less | 8 - .../notification/examples/1/index.ts | 17 +- .../notification/examples/2/index.less | 0 .../notification/examples/2/index.ts | 3 +- .../notification/examples/3/index.html | 240 ++---------------- .../notification/examples/3/index.less | 9 +- .../notification/examples/3/index.ts | 10 +- .../notification/examples/import/template.md | 8 +- .../components/notification/index.html | 43 +--- .../modules/components/notification/index.ts | 13 +- .../modules/components/pdf-viewer/index.html | 18 +- .../modules/components/pie-chart/index.html | 20 +- .../components/primitive-textfield/index.html | 48 ++-- .../progress-bar/examples/3/index.html | 6 - .../components/progress-bar/index.html | 1 - .../components/pull-to-refresh/index.html | 8 +- .../src/modules/components/radio/index.html | 24 +- .../src/modules/components/range/index.html | 26 +- .../modules/components/scrollbar/index.html | 8 +- .../src/modules/components/select/index.html | 24 +- .../src/modules/components/sheet/index.html | 50 ++-- .../src/modules/components/slider/index.html | 26 +- .../src/modules/components/surface/index.html | 54 ++-- .../src/modules/components/switch/index.html | 8 +- .../components/tab-bar/examples/1/index.less | 1 + .../components/tab-bar/examples/2/index.html | 2 +- .../components/tab-bar/examples/3/index.less | 1 + .../src/modules/components/tab-bar/index.html | 22 +- .../src/modules/components/tab-bar/index.less | 1 - .../src/modules/components/tabs/index.html | 12 +- .../modules/components/textarea/index.html | 12 +- .../modules/components/textfield/index.html | 7 +- .../customization/dialogs/examples/1/index.ts | 4 +- .../src/modules/directives/hint/index.html | 12 +- .../src/modules/directives/resizer/index.html | 10 +- .../modules/directives/sensitive/index.html | 18 +- .../demo/src/modules/info/browsers/index.html | 16 +- .../demo/src/modules/markup/tables/index.html | 20 +- .../src/modules/markup/typography/index.html | 26 +- .../pipes/stringify-content/index.html | 18 +- .../src/modules/pipes/stringify/index.html | 32 +-- projects/demo/used-icons.ts | 1 - 123 files changed, 1016 insertions(+), 1422 deletions(-) delete mode 100644 projects/core/components/notification/notification.component.ts create mode 100644 projects/core/components/notification/notification.directive.ts delete mode 100644 projects/core/components/notification/notification.style.less delete mode 100644 projects/core/components/notification/notification.template.html delete mode 100644 projects/core/components/notification/test/notification.component.spec.ts create mode 100644 projects/core/styles/components/notification.less delete mode 100644 projects/demo-playwright/tests/kit/notification/notification.spec.ts delete mode 100644 projects/demo/src/modules/components/notification/examples/2/index.less diff --git a/projects/addon-charts/components/axes/axes.style.less b/projects/addon-charts/components/axes/axes.style.less index f51363f5b097..1f12d8f5cfc5 100644 --- a/projects/addon-charts/components/axes/axes.style.less +++ b/projects/addon-charts/components/axes/axes.style.less @@ -112,6 +112,7 @@ } .t-labels-x { + position: relative; display: flex; font: var(--tui-font-text-xs); border-right: 1px solid transparent; @@ -141,16 +142,13 @@ margin: 0; } - :host[new]:not(._centered) & { + :host:not(._centered) & { &:last-child:not(:first-child) { - flex: 0.5; + position: absolute; + right: 0; text-align: right; border-left: none; } - - &:nth-last-child(2) { - flex: 0.5; - } } } diff --git a/projects/addon-doc/components/code/index.less b/projects/addon-doc/components/code/index.less index 221ead73de47..6b5db11bb090 100644 --- a/projects/addon-doc/components/code/index.less +++ b/projects/addon-doc/components/code/index.less @@ -3,7 +3,6 @@ :host { display: block; - overflow: hidden; } .t-header { diff --git a/projects/addon-doc/components/example/example.component.ts b/projects/addon-doc/components/example/example.component.ts index 30cd991bbddb..e7bf768f18ed 100644 --- a/projects/addon-doc/components/example/example.component.ts +++ b/projects/addon-doc/components/example/example.component.ts @@ -140,7 +140,7 @@ export class TuiDocExample { protected copyExampleLink(target: EventTarget | null): void { this.clipboard.copy((target as HTMLAnchorElement | null)?.href ?? ''); this.alerts - .open(this.texts[1], {label: this.texts[2], status: 'success'}) + .open(this.texts[1], {label: this.texts[2], appearance: 'success'}) .subscribe(); } diff --git a/projects/addon-doc/components/example/example.style.less b/projects/addon-doc/components/example/example.style.less index e4f56581a2b0..a4b42cc9c2fb 100644 --- a/projects/addon-doc/components/example/example.style.less +++ b/projects/addon-doc/components/example/example.style.less @@ -110,3 +110,7 @@ visibility: visible; opacity: 1; } + +tui-doc-code { + overflow: hidden; +} diff --git a/projects/addon-doc/components/main/main.component.ts b/projects/addon-doc/components/main/main.component.ts index 7abd6ae184ff..5ac2edd9fc43 100644 --- a/projects/addon-doc/components/main/main.component.ts +++ b/projects/addon-doc/components/main/main.component.ts @@ -8,7 +8,6 @@ import { import {RouterOutlet} from '@angular/router'; import {TuiDocThemeDarkService} from '@taiga-ui/addon-doc/services'; import {TUI_DOC_ICONS} from '@taiga-ui/addon-doc/tokens'; -import {TuiSwipeService} from '@taiga-ui/cdk/directives/swipe'; import {TuiButton} from '@taiga-ui/core/components/button'; import {TuiRoot} from '@taiga-ui/core/components/root'; @@ -29,10 +28,9 @@ import {TuiDocNavigation} from '../navigation/navigation.component'; templateUrl: './main.template.html', styleUrls: ['./main.style.less'], encapsulation: ViewEncapsulation.None, - // @note: This one was default on purpose so we can test demo in default mode. + // @note: This one was default on purpose, so we can test demo in default mode. // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection changeDetection: ChangeDetectionStrategy.Default, - providers: [TuiSwipeService], }) export class TuiDocMain { private readonly icons = inject(TUI_DOC_ICONS); diff --git a/projects/addon-doc/components/main/main.style.less b/projects/addon-doc/components/main/main.style.less index 47619df54288..573af1723217 100644 --- a/projects/addon-doc/components/main/main.style.less +++ b/projects/addon-doc/components/main/main.style.less @@ -61,6 +61,10 @@ code:not(pre code) { text-wrap: wrap; tui-notification & { + mix-blend-mode: color-burn; + } + + [tuiTheme='dark'] tui-notification & { mix-blend-mode: luminosity; } diff --git a/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts b/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts index 38c124b3a531..46b76c81a4ca 100644 --- a/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts +++ b/projects/cdk/schematics/ng-update/v4/steps/constants/identifiers-to-replace.ts @@ -85,10 +85,6 @@ export const IDENTIFIERS_TO_REPLACE: ReplacementIdentifierMulti[] = [ from: {name: 'TuiNotificationModule', moduleSpecifier: '@taiga-ui/core'}, to: {name: 'TuiNotification', moduleSpecifier: '@taiga-ui/core'}, }, - { - from: {name: 'TuiNotificationT', moduleSpecifier: '@taiga-ui/core'}, - to: {name: 'TuiNotificationStatus', moduleSpecifier: '@taiga-ui/core'}, - }, { from: {name: 'TuiFormatPhonePipe', moduleSpecifier: '@taiga-ui/core'}, to: {name: 'TuiFormatPhonePipe', moduleSpecifier: '@taiga-ui/legacy'}, diff --git a/projects/cdk/schematics/ng-update/v4/steps/constants/types.ts b/projects/cdk/schematics/ng-update/v4/steps/constants/types.ts index 0dc400bab169..497ec5a3920f 100644 --- a/projects/cdk/schematics/ng-update/v4/steps/constants/types.ts +++ b/projects/cdk/schematics/ng-update/v4/steps/constants/types.ts @@ -22,6 +22,12 @@ export const TYPES_TO_RENAME: readonly ReplacementType[] = [ to: 'string', removeImport: true, }, + { + from: 'TuiNotificationT', + moduleSpecifier: ['@taiga-ui/core'], + to: 'string', + removeImport: true, + }, { from: 'TuiOperationIcon', moduleSpecifier: ['@taiga-ui/proprietary-banking'], diff --git a/projects/core/components/alert/alert.component.ts b/projects/core/components/alert/alert.component.ts index c81154ef6321..c1b76f8ffa26 100644 --- a/projects/core/components/alert/alert.component.ts +++ b/projects/core/components/alert/alert.component.ts @@ -1,19 +1,20 @@ import {NgIf} from '@angular/common'; -import type {OnInit} from '@angular/core'; -import {ChangeDetectionStrategy, Component, DestroyRef, inject} from '@angular/core'; -import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; +import {ChangeDetectionStrategy, Component, inject} from '@angular/core'; +import {takeUntilDestroyed, toSignal} from '@angular/core/rxjs-interop'; import type {TuiPopover} from '@taiga-ui/cdk/services'; import {tuiInjectElement} from '@taiga-ui/cdk/utils/dom'; import {tuiFadeIn, tuiHeightCollapse, tuiSlideIn} from '@taiga-ui/core/animations'; +import {TuiButton} from '@taiga-ui/core/components/button'; import {TuiNotification} from '@taiga-ui/core/components/notification'; -import {TUI_ANIMATIONS_SPEED} from '@taiga-ui/core/tokens'; -import {tuiToAnimationOptions} from '@taiga-ui/core/utils'; +import {TuiTitle} from '@taiga-ui/core/directives/title'; import { - POLYMORPHEUS_CONTEXT, - PolymorpheusOutlet, - PolymorpheusTemplate, -} from '@taiga-ui/polymorpheus'; -import {fromEvent, repeat, takeUntil, timer} from 'rxjs'; + TUI_ANIMATIONS_SPEED, + TUI_CLOSE_WORD, + TUI_COMMON_ICONS, +} from '@taiga-ui/core/tokens'; +import {tuiToAnimationOptions} from '@taiga-ui/core/utils'; +import {POLYMORPHEUS_CONTEXT, PolymorpheusOutlet} from '@taiga-ui/polymorpheus'; +import {EMPTY, fromEvent, of, repeat, switchMap, takeUntil, timer} from 'rxjs'; import type {TuiAlertOptions} from './alert.interfaces'; import {TUI_ALERT_POSITION} from './alert.tokens'; @@ -21,7 +22,7 @@ import {TUI_ALERT_POSITION} from './alert.tokens'; @Component({ standalone: true, selector: 'tui-alert', - imports: [TuiNotification, NgIf, PolymorpheusOutlet, PolymorpheusTemplate], + imports: [NgIf, PolymorpheusOutlet, TuiNotification, TuiButton, TuiTitle], templateUrl: './alert.template.html', styleUrls: ['./alert.style.less'], changeDetection: ChangeDetectionStrategy.OnPush, @@ -34,43 +35,30 @@ import {TUI_ALERT_POSITION} from './alert.tokens'; '[@tuiHeightCollapse]': 'animation', }, }) -export class TuiAlertComponent implements OnInit { +export class TuiAlertComponent { private readonly el = tuiInjectElement(); - private readonly destroyRef = inject(DestroyRef); + + protected readonly icons = inject(TUI_COMMON_ICONS); + protected readonly options = tuiToAnimationOptions(inject(TUI_ANIMATIONS_SPEED)); + protected readonly close = toSignal(inject(TUI_CLOSE_WORD)); protected readonly position = inject(TUI_ALERT_POSITION); protected readonly item = inject, O>>(POLYMORPHEUS_CONTEXT); - protected readonly autoClose = - typeof this.item.autoClose === 'function' - ? this.item.autoClose(this.item.status) - : this.item.autoClose; - - protected readonly options = tuiToAnimationOptions(inject(TUI_ANIMATIONS_SPEED)); - protected readonly animation = this.position.endsWith('auto') ? {...this.options, value: 'right'} : {...this.options, value: 'left'}; - public ngOnInit(): void { - this.initAutoClose(); - } - - protected close(): void { - this.item.$implicit.complete(); - } - - private initAutoClose(): void { - if (!this.autoClose) { - return; - } - - timer(this.autoClose) - .pipe( - takeUntil(fromEvent(this.el, 'mouseenter')), - repeat({delay: () => fromEvent(this.el, 'mouseleave')}), - takeUntilDestroyed(this.destroyRef), - ) - .subscribe(() => this.close()); - } + protected readonly sub = of( + typeof this.item.autoClose === 'function' + ? this.item.autoClose(this.item.appearance) + : this.item.autoClose, + ) + .pipe( + switchMap((autoClose) => (autoClose ? timer(autoClose) : EMPTY)), + takeUntil(fromEvent(this.el, 'mouseenter')), + repeat({delay: () => fromEvent(this.el, 'mouseleave')}), + takeUntilDestroyed(), + ) + .subscribe(() => this.item.$implicit.complete()); } diff --git a/projects/core/components/alert/alert.interfaces.ts b/projects/core/components/alert/alert.interfaces.ts index da7f6b752cbe..c20a88e7bbd4 100644 --- a/projects/core/components/alert/alert.interfaces.ts +++ b/projects/core/components/alert/alert.interfaces.ts @@ -1,16 +1,11 @@ import type {TuiPopoverContext} from '@taiga-ui/cdk/services'; import type {TuiHandler} from '@taiga-ui/cdk/types'; -import type { - TuiNotificationOptions, - TuiNotificationStatus, -} from '@taiga-ui/core/components/notification'; +import type {TuiNotificationOptions} from '@taiga-ui/core/components/notification'; import type {PolymorpheusContent} from '@taiga-ui/polymorpheus'; -export type TuiAlertAutoClose = TuiHandler | number; - export interface TuiAlertOptions extends Omit { - readonly autoClose: TuiAlertAutoClose; + readonly autoClose: TuiHandler | number; readonly data: I; readonly closeable: boolean; readonly label: PolymorpheusContent>; diff --git a/projects/core/components/alert/alert.style.less b/projects/core/components/alert/alert.style.less index bf4167e4e53c..ce2fcc2f4a0a 100644 --- a/projects/core/components/alert/alert.style.less +++ b/projects/core/components/alert/alert.style.less @@ -2,9 +2,11 @@ :host { display: block; - box-shadow: var(--tui-shadow-medium); - border-radius: var(--tui-radius-l); width: 18rem; + flex-shrink: 0; + background: var(--tui-background-elevation-1); + border-radius: var(--tui-radius-m); + box-shadow: var(--tui-shadow-medium); &:not(:first-child) { margin-top: 0.75rem !important; @@ -14,34 +16,3 @@ margin-bottom: 0 !important; } } - -.t-heading { - margin: 0; - - [data-size='s'] & { - font: var(--tui-font-text-s); - font-weight: bold; - } - - [data-size='m'] & { - font: var(--tui-font-text-m); - line-height: 1.25rem; - font-weight: bold; - } - - [data-size='l'] & { - font: var(--tui-font-text-l); - line-height: 1.5rem; - font-weight: bold; - } -} - -.t-content { - color: var(--tui-text-primary); - word-wrap: break-word; - word-break: break-word; - - &:empty { - display: none; - } -} diff --git a/projects/core/components/alert/alert.template.html b/projects/core/components/alert/alert.template.html index 2e470327d37b..21f647a2fcc7 100644 --- a/projects/core/components/alert/alert.template.html +++ b/projects/core/components/alert/alert.template.html @@ -1,25 +1,25 @@ - -
+ + + +
+ {{ close() }} +
diff --git a/projects/core/components/alert/alert.tokens.ts b/projects/core/components/alert/alert.tokens.ts index 5dacfb74ae00..29835a238280 100644 --- a/projects/core/components/alert/alert.tokens.ts +++ b/projects/core/components/alert/alert.tokens.ts @@ -11,7 +11,7 @@ import {BehaviorSubject, combineLatest, map, of} from 'rxjs'; import type {TuiAlertOptions} from './alert.interfaces'; -export const TUI_ALERT_DEFAULT_OPTIONS: Omit = { +export const TUI_ALERT_DEFAULT_OPTIONS: Omit = { autoClose: 3000, label: '', closeable: true, diff --git a/projects/core/components/notification/index.ts b/projects/core/components/notification/index.ts index 2b528ce845f4..1a34151f25ca 100644 --- a/projects/core/components/notification/index.ts +++ b/projects/core/components/notification/index.ts @@ -1,2 +1,2 @@ -export * from './notification.component'; +export * from './notification.directive'; export * from './notification.options'; diff --git a/projects/core/components/notification/notification.component.ts b/projects/core/components/notification/notification.component.ts deleted file mode 100644 index 0d713d27aceb..000000000000 --- a/projects/core/components/notification/notification.component.ts +++ /dev/null @@ -1,63 +0,0 @@ -import {AsyncPipe, NgIf} from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - EventEmitter, - HostBinding, - inject, - Input, - Output, -} from '@angular/core'; -import type {TuiContext} from '@taiga-ui/cdk/types'; -import {TuiButton} from '@taiga-ui/core/components/button'; -import {TuiIcon} from '@taiga-ui/core/components/icon'; -import {TUI_CLOSE_WORD, TUI_COMMON_ICONS} from '@taiga-ui/core/tokens'; -import type {PolymorpheusContent} from '@taiga-ui/polymorpheus'; -import {PolymorpheusOutlet, PolymorpheusTemplate} from '@taiga-ui/polymorpheus'; - -import type {TuiNotificationStatus} from './notification.options'; -import {TUI_NOTIFICATION_OPTIONS} from './notification.options'; - -@Component({ - standalone: true, - selector: 'tui-notification,a[tuiNotification],button[tuiNotification]', - imports: [ - TuiButton, - PolymorpheusOutlet, - PolymorpheusTemplate, - NgIf, - TuiIcon, - AsyncPipe, - ], - templateUrl: './notification.template.html', - styleUrls: ['./notification.style.less'], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class TuiNotification { - private readonly options = inject(TUI_NOTIFICATION_OPTIONS); - - protected readonly closeWord$ = inject(TUI_CLOSE_WORD); - protected readonly icons = inject(TUI_COMMON_ICONS); - - @Input() - public icon: PolymorpheusContent> = - this.options.icon; - - @Input() - @HostBinding('attr.data-status') - public status = this.options.status; - - @Input() - @HostBinding('attr.data-size') - public size = this.options.size; - - @Input() - public hideClose = false; - - @Output() - public readonly close = new EventEmitter(); - - protected get hasClose(): boolean { - return !this.hideClose && this.close.observed; - } -} diff --git a/projects/core/components/notification/notification.directive.ts b/projects/core/components/notification/notification.directive.ts new file mode 100644 index 000000000000..f7e7872b2033 --- /dev/null +++ b/projects/core/components/notification/notification.directive.ts @@ -0,0 +1,80 @@ +import type {OnChanges, OnInit} from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + Directive, + HostBinding, + inject, + Input, + ViewEncapsulation, +} from '@angular/core'; +import type {TuiStringHandler} from '@taiga-ui/cdk/types'; +import {tuiIsString, tuiWithStyles} from '@taiga-ui/cdk/utils/miscellaneous'; +import {tuiButtonOptionsProvider} from '@taiga-ui/core/components/button'; +import {tuiLinkOptionsProvider} from '@taiga-ui/core/components/link'; +import { + tuiAppearanceOptionsProvider, + TuiWithAppearance, +} from '@taiga-ui/core/directives/appearance'; +import {TuiIcons, TuiWithIcons} from '@taiga-ui/core/directives/icons'; + +import {TUI_NOTIFICATION_OPTIONS} from './notification.options'; + +@Component({ + standalone: true, + template: '', + styles: ['@import "@taiga-ui/core/styles/components/notification.less";'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: 'tui-notification', + }, +}) +class TuiNotificationStyles {} + +@Directive({ + standalone: true, + selector: 'tui-notification,a[tuiNotification],button[tuiNotification]', + providers: [ + tuiAppearanceOptionsProvider(TUI_NOTIFICATION_OPTIONS), + tuiLinkOptionsProvider({ + appearance: '', + pseudo: true, + }), + tuiButtonOptionsProvider({ + appearance: 'whiteblock', + size: 's', + }), + ], + hostDirectives: [TuiWithIcons, TuiWithAppearance], +}) +export class TuiNotification implements OnChanges, OnInit { + private readonly options = inject(TUI_NOTIFICATION_OPTIONS); + + protected readonly nothing = tuiWithStyles(TuiNotificationStyles); + protected readonly icons = inject(TuiIcons); + + @Input() + public appearance = this.options.appearance; + + @Input() + public icon: TuiStringHandler | string = this.options.icon; + + @Input() + @HostBinding('attr.data-size') + public size = this.options.size; + + public ngOnInit(): void { + this.refresh(); + } + + public ngOnChanges(): void { + this.refresh(); + } + + private refresh(): void { + this.icons.iconStart = tuiIsString(this.icon) + ? this.icon + : this.icon(this.appearance); + } +} diff --git a/projects/core/components/notification/notification.options.ts b/projects/core/components/notification/notification.options.ts index bc84e0b6df1f..5c631f3a781c 100644 --- a/projects/core/components/notification/notification.options.ts +++ b/projects/core/components/notification/notification.options.ts @@ -1,30 +1,27 @@ import type {Provider} from '@angular/core'; -import type {TuiContext} from '@taiga-ui/cdk/types'; +import type {TuiStringHandler} from '@taiga-ui/cdk/types'; import {tuiCreateToken, tuiProvideOptions} from '@taiga-ui/cdk/utils/miscellaneous'; +import type {TuiAppearanceOptions} from '@taiga-ui/core/directives/appearance'; import type {TuiSizeL, TuiSizeS} from '@taiga-ui/core/types'; -import type {PolymorpheusContent} from '@taiga-ui/polymorpheus'; -export type TuiNotificationStatus = 'error' | 'info' | 'neutral' | 'success' | 'warning'; - -export interface TuiNotificationOptions { - readonly status: TuiNotificationStatus; - readonly icon: PolymorpheusContent>; +export interface TuiNotificationOptions extends TuiAppearanceOptions { + readonly icon: TuiStringHandler | string; readonly size: TuiSizeL | TuiSizeS; } -const STATUS_ICON = { +const ICONS: Record = { info: '@tui.info', success: '@tui.circle-check', error: '@tui.circle-x', warning: '@tui.circle-alert', neutral: '@tui.info', -} as const; +}; /** Default values for the notification options. */ export const TUI_NOTIFICATION_DEFAULT_OPTIONS: TuiNotificationOptions = { - status: 'info', - icon: ({$implicit}) => STATUS_ICON[$implicit], - size: 'm', + appearance: 'info', + icon: (appearance) => ICONS[appearance], + size: 'l', }; /** diff --git a/projects/core/components/notification/notification.style.less b/projects/core/components/notification/notification.style.less deleted file mode 100644 index 9dfa4d4150c4..000000000000 --- a/projects/core/components/notification/notification.style.less +++ /dev/null @@ -1,126 +0,0 @@ -@import '@taiga-ui/core/styles/taiga-ui-local'; - -:host { - position: relative; - display: flex; - font: var(--tui-font-text-s); - color: var(--tui-text-primary); - padding: 0.75rem 1rem; - border-radius: var(--tui-radius-m); - background: #fff; // fallback for IE - background: var(--tui-background-base); - box-sizing: border-box; - overflow: hidden; - text-align: left; - - .t-more { - display: none; - } - - &button, - &a { - border: none; - cursor: pointer; - - .t-more { - display: inline-flex; - width: 1rem; - color: var(--tui-text-primary); - opacity: 0.5; - } - } - - &[data-size='s'] { - padding: 0.375rem 0.625rem; - - .t-icon { - width: 1rem; - height: 1.25rem; - margin: 0 0.375rem 0 -0.125rem; - } - - .t-close { - margin: -0.125rem -0.375rem -0.125rem 0.75rem; - } - - .t-more { - margin: -0.125rem -0.375rem -0.125rem 0; - } - } - - &[data-size='m'] { - padding: 0.75rem; - - .t-icon { - width: 1.25rem; - height: 1.25rem; - margin-right: 0.5rem; - } - - .t-close { - margin: -0.125rem -0.125rem -0.125rem 1rem; - } - - .t-more { - margin: -0.125rem -0.375rem -0.125rem 0; - } - } - - &[data-size='l'] { - padding: 1rem; - font: var(--tui-font-text-m); - border-radius: var(--tui-radius-l); - - .t-icon { - width: 1.5rem; - height: 1.5rem; - margin-right: 0.5rem; - } - - .t-more { - margin-right: -0.5rem; - } - } - - &[data-status='info'] { - color: var(--tui-status-info); - background: linear-gradient(var(--tui-status-info-pale), var(--tui-status-info-pale)), - var(--tui-background-base); - } - - &[data-status='success'] { - color: var(--tui-status-positive); - background: linear-gradient(var(--tui-status-positive-pale), var(--tui-status-positive-pale)), - var(--tui-background-base); - } - - &[data-status='error'] { - color: var(--tui-status-negative); - background: linear-gradient(var(--tui-status-negative-pale), var(--tui-status-negative-pale)), - var(--tui-background-base); - } - - &[data-status='warning'] { - color: var(--tui-status-warning); - background: linear-gradient(var(--tui-status-warning-pale), var(--tui-status-warning-pale)), - var(--tui-background-base); - } - - &[data-status='neutral'] { - color: var(--tui-status-neutral); - background: linear-gradient(var(--tui-background-neutral-1), var(--tui-background-neutral-1)), - var(--tui-background-base); - } -} - -:host-context([tuiTheme='dark']) { - --tui-background-base: #000; -} - -.t-content { - flex: 1; - word-break: break-word; - color: var(--tui-text-primary); - text-align: inherit; - align-self: center; -} diff --git a/projects/core/components/notification/notification.template.html b/projects/core/components/notification/notification.template.html deleted file mode 100644 index a9560aa4cb11..000000000000 --- a/projects/core/components/notification/notification.template.html +++ /dev/null @@ -1,29 +0,0 @@ - - - -
- -
- - diff --git a/projects/core/components/notification/test/notification.component.spec.ts b/projects/core/components/notification/test/notification.component.spec.ts deleted file mode 100644 index a8030e3fc397..000000000000 --- a/projects/core/components/notification/test/notification.component.spec.ts +++ /dev/null @@ -1,138 +0,0 @@ -import {NgIf} from '@angular/common'; -import type {DebugElement} from '@angular/core'; -import {Component, ViewChild} from '@angular/core'; -import type {ComponentFixture} from '@angular/core/testing'; -import {TestBed} from '@angular/core/testing'; -import type {TuiNotificationStatus} from '@taiga-ui/core'; -import { - TUI_NOTIFICATION_DEFAULT_OPTIONS, - TUI_NOTIFICATION_OPTIONS, - TuiNotification, -} from '@taiga-ui/core'; -import {NG_EVENT_PLUGINS} from '@taiga-ui/event-plugins'; -import {TuiPageObject} from '@taiga-ui/testing'; - -describe('Notification', () => { - describe('Without options', () => { - @Component({ - standalone: true, - imports: [TuiNotification, NgIf], - template: ` - - Short simple informational message - - - - Short simple informational message - - - `, - }) - class Test { - @ViewChild(TuiNotification, {static: false}) - public component!: TuiNotification; - - public hasCloseButton = true; - public status: TuiNotificationStatus = 'info'; - - public onClose(): void {} - } - - let fixture: ComponentFixture; - let testComponent: Test; - let pageObject: TuiPageObject; - - function getIcon(): DebugElement { - return pageObject.getByAutomationId('tui-notification__icon')!; - } - - function getClose(): DebugElement { - return pageObject.getByAutomationId('tui-notification__close')!; - } - - beforeEach(async () => { - TestBed.configureTestingModule({ - imports: [Test], - providers: [NG_EVENT_PLUGINS], - }); - await TestBed.compileComponents(); - fixture = TestBed.createComponent(Test); - pageObject = new TuiPageObject(fixture); - testComponent = fixture.componentInstance; - fixture.detectChanges(); - }); - - describe('icon', () => { - it('present by default', () => { - expect(getIcon()).not.toBeNull(); - }); - }); - - describe('closing cross', () => { - it('present when subscribing to close', () => { - expect(getClose()).not.toBeNull(); - }); - - it('without subscription to close is missing', () => { - testComponent.hasCloseButton = false; - fixture.detectChanges(); - - expect(getClose()).toBeNull(); - }); - }); - }); - - describe('With options', () => { - @Component({ - standalone: true, - imports: [TuiNotification], - template: ` - Short simple informational message - `, - }) - class Test { - @ViewChild(TuiNotification, {static: false}) - public component!: TuiNotification; - } - - const status = 'error'; - - let fixture: ComponentFixture; - let pageObject: TuiPageObject; - - function getIcon(): DebugElement { - return pageObject.getByAutomationId('tui-notification__icon')!; - } - - beforeEach(async () => { - TestBed.configureTestingModule({ - imports: [Test], - providers: [ - { - provide: TUI_NOTIFICATION_OPTIONS, - useValue: { - ...TUI_NOTIFICATION_DEFAULT_OPTIONS, - status, - icon: null, - }, - }, - ], - }); - await TestBed.compileComponents(); - - fixture = TestBed.createComponent(Test); - pageObject = new TuiPageObject(fixture); - fixture.detectChanges(); - }); - - describe('icon', () => { - it('when icon = null is absent', () => { - expect(getIcon()).toBeNull(); - }); - }); - }); -}); diff --git a/projects/core/components/textfield/textfield.style.less b/projects/core/components/textfield/textfield.style.less index 4c8b9f5a03d0..acba30f1fe5a 100644 --- a/projects/core/components/textfield/textfield.style.less +++ b/projects/core/components/textfield/textfield.style.less @@ -231,6 +231,11 @@ } }); } + + ::ng-deep button, + ::ng-deep a { + pointer-events: auto; + } } .t-content { diff --git a/projects/core/styles/components/icons.less b/projects/core/styles/components/icons.less index 0a4a7721d4a0..aa830df623c5 100644 --- a/projects/core/styles/components/icons.less +++ b/projects/core/styles/components/icons.less @@ -16,13 +16,13 @@ * Button, Icon, Link */ [tuiIcons] { - --t-display-start: var(--t-icon-start, none); - --t-display-end: var(--t-icon-end, none); + --t-icon-start: none; + --t-icon-end: none; &:before, &:after { content: ''; - display: var(--t-display-start); + display: var(--t-icon-start); width: 1em; height: 1em; font-size: 1.5rem; @@ -32,7 +32,7 @@ } &:after { - display: var(--t-display-end); + display: var(--t-icon-end); mask: var(--t-icon-end) no-repeat center/contain; } } diff --git a/projects/core/styles/components/notification.less b/projects/core/styles/components/notification.less new file mode 100644 index 000000000000..6628739df79b --- /dev/null +++ b/projects/core/styles/components/notification.less @@ -0,0 +1,123 @@ +@import '@taiga-ui/core/styles/taiga-ui-local'; + +tui-notification, +[tuiNotification] { + .button-clear(); + + position: relative; + display: flex; + max-height: 100%; + color: var(--tui-text-primary); + font: var(--tui-font-text-s); + border-radius: var(--tui-radius-m); + box-sizing: border-box; + overflow: hidden; + text-align: left; + text-decoration: none; + border: 0 solid transparent; + + &:after { + font-size: 1rem; + margin: 0 -0.25rem 0 auto; + align-self: center; + color: var(--tui-text-tertiary) !important; + } + + &[data-size='s'] { + gap: 0.5rem; + padding: 0.375rem 0.625rem; + + &:before, + tui-icon { + font-size: 1rem; + margin-top: 0.125rem; + margin-bottom: 0.125rem; + } + + [tuiTitle] { + font: var(--tui-font-text-s); + font-weight: bold; + } + + [tuiSubtitle] + * { + gap: 1rem; + margin: 0.375rem 0 0.25rem; + } + + > [tuiIconButton] { + margin: -0.375rem -0.625rem -0.375rem auto; + } + } + + &[data-size='m'] { + gap: 0.375rem; + padding: 0.75rem; + + &:before, + tui-icon { + font-size: 1.25rem; + } + + [tuiTitle] { + font: var(--tui-font-text-ui-m); + font-weight: bold; + } + + [tuiSubtitle] + * { + gap: 1rem; + margin: 0.625rem 0 0.25rem; + } + + > [tuiIconButton] { + margin: -0.375rem -0.25rem -0.375rem auto; + } + } + + &[data-size='l'] { + gap: 0.5rem; + padding: 1rem; + font: var(--tui-font-text-m); + border-radius: var(--tui-radius-l); + + [tuiTitle] { + font: var(--tui-font-text-ui-l); + font-weight: bold; + } + + [tuiSubtitle] { + font: var(--tui-font-text-m); + + + * { + gap: 1.25rem; + margin-top: 0.625rem; + } + } + + > [tuiIconButton] { + margin: -0.25rem -0.25rem -0.25rem auto; + } + } + + [tuiTitle] { + gap: 0.125rem; + } + + [tuiSubtitle] { + font: var(--tui-font-text-s); + + + * { + display: flex; + font: var(--tui-font-text-s); + align-items: center; + } + } + + > [tuiIconButton] { + box-shadow: none !important; + background: transparent !important; + } +} + +[tuiNotification] { + cursor: pointer; +} diff --git a/projects/core/styles/theme/appearance/icon.less b/projects/core/styles/theme/appearance/icon.less index bf21f6d2d45c..ecd72e86257f 100644 --- a/projects/core/styles/theme/appearance/icon.less +++ b/projects/core/styles/theme/appearance/icon.less @@ -14,7 +14,6 @@ // Icons with the directive [tuiAppearance][data-appearance='whiteblock'], -[tuiAppearance][data-appearance='neutral'], [tuiAppearance][data-appearance='floating'] { &:before, &:after { diff --git a/projects/core/styles/theme/appearance/status.less b/projects/core/styles/theme/appearance/status.less index cdffa6a1ee7d..c7bf2522159d 100644 --- a/projects/core/styles/theme/appearance/status.less +++ b/projects/core/styles/theme/appearance/status.less @@ -15,7 +15,10 @@ [tuiAppearance][data-appearance='error'] { --t-bg: var(--tui-status-negative-pale); - color: var(--tui-status-negative); + &:before, + &:after { + color: var(--tui-status-negative); + } .appearance-hover({ --t-bg: var(--tui-status-negative-pale-hover); @@ -33,7 +36,10 @@ [tuiAppearance][data-appearance='success'] { --t-bg: var(--tui-status-positive-pale); - color: var(--tui-status-positive); + &:before, + &:after { + color: var(--tui-status-positive); + } .appearance-hover({ --t-bg: var(--tui-status-positive-pale-hover); @@ -51,7 +57,10 @@ [tuiAppearance][data-appearance='warning'] { --t-bg: var(--tui-status-warning-pale); - color: var(--tui-status-warning); + &:before, + &:after { + color: var(--tui-status-warning); + } .appearance-hover({ --t-bg: var(--tui-status-warning-pale-hover); @@ -69,7 +78,10 @@ [tuiAppearance][data-appearance='info'] { --t-bg: var(--tui-status-info-pale); - color: var(--tui-status-info); + &:before, + &:after { + color: var(--tui-status-info); + } .appearance-hover({ --t-bg: var(--tui-status-info-pale-hover); @@ -87,7 +99,10 @@ [tuiAppearance][data-appearance='neutral'] { --t-bg: var(--tui-background-neutral-1); - color: var(--tui-status-neutral); + &:before, + &:after { + color: var(--tui-status-neutral); + } .appearance-hover({ --t-bg: var(--tui-background-neutral-1-hover); diff --git a/projects/demo-playwright/tests/kit/notification/notification.spec.ts b/projects/demo-playwright/tests/kit/notification/notification.spec.ts deleted file mode 100644 index 2a8864880a1d..000000000000 --- a/projects/demo-playwright/tests/kit/notification/notification.spec.ts +++ /dev/null @@ -1,39 +0,0 @@ -import {DemoRoute} from '@demo/routes'; -import {TuiDocumentationPagePO, tuiGoto} from '@demo-playwright/utils'; -import type {Locator} from '@playwright/test'; -import {expect, test} from '@playwright/test'; - -test.describe('Notification', () => { - const viewports = generateDimensions(180, 320, 10); - let example: Locator; - - test.describe('default', () => { - test.beforeEach(async ({page}) => { - await tuiGoto(page, `${DemoRoute.Notification}/API`); - - example = new TuiDocumentationPagePO(page).apiPageExample; - }); - - viewports.forEach(({width, height}) => { - test(`width: ${width}`, async ({page}) => { - await page.setViewportSize({width, height}); - await expect(example).toHaveScreenshot(`01-notification-${width}.png`); - }); - }); - }); -}); - -interface Dimensions { - width: number; - height: number; -} - -function generateDimensions(start: number, end: number, step: number): Dimensions[] { - const viewports: Dimensions[] = []; - - for (let width = start; width <= end; width += step) { - viewports.push({width, height: 500}); - } - - return viewports; -} diff --git a/projects/demo/src/modules/app/app.config.ts b/projects/demo/src/modules/app/app.config.ts index 8dd3720a30db..c7de4e122bd4 100644 --- a/projects/demo/src/modules/app/app.config.ts +++ b/projects/demo/src/modules/app/app.config.ts @@ -1,7 +1,6 @@ import {isPlatformBrowser, LocationStrategy, PathLocationStrategy} from '@angular/common'; import type {ApplicationConfig} from '@angular/core'; import {inject, PLATFORM_ID, provideZoneChangeDetection} from '@angular/core'; -import {Title} from '@angular/platform-browser'; import {provideAnimations} from '@angular/platform-browser/animations'; import type {UrlTree} from '@angular/router'; import {provideRouter, withInMemoryScrolling} from '@angular/router'; @@ -28,6 +27,7 @@ import { TUI_DROPDOWN_HOVER_OPTIONS, TUI_HINT_DEFAULT_OPTIONS, TUI_HINT_OPTIONS, + tuiNotificationOptionsProvider, } from '@taiga-ui/core'; import {NG_EVENT_PLUGINS} from '@taiga-ui/event-plugins'; import type {TuiLanguageName} from '@taiga-ui/i18n'; @@ -54,7 +54,7 @@ export const config: ApplicationConfig = { }), ), NG_EVENT_PLUGINS, - Title, + tuiNotificationOptionsProvider({size: 'm'}), { provide: TUI_PLATFORM, useValue: 'web', diff --git a/projects/demo/src/modules/app/home/home.template.html b/projects/demo/src/modules/app/home/home.template.html index 7bedca7a8a4c..e35281e3992e 100644 --- a/projects/demo/src/modules/app/home/home.template.html +++ b/projects/demo/src/modules/app/home/home.template.html @@ -157,23 +157,6 @@

Manual

npm i @taiga-ui/styles and put this code: - - In version 3.0 we drop to support normalize(v7) out-of-the-box! -

- You need to manually - - download css file - - , if you're looking to use reset styles or you can write your own reset.css -

-
- Manual /> - Also you can use not all styles from global, but only what you need partially import, for - example - @taiga-ui/styles/markup/tui-mobile-only - , or something: +
+ Also you can use not all styles from global, but only the ones you need, for example + @taiga-ui/styles/markup/tui-mobile-only + or something else from the list below: +
- To use this you need to add optional - @taiga-ui/styles - package and include - @taiga-ui/styles/taiga-ui-global - in your global styles. - - Read more. - +
+ To use this you need to add optional + @taiga-ui/styles + package and include + @taiga-ui/styles/taiga-ui-global + in your global styles. + + Read more. + +
diff --git a/projects/demo/src/modules/components/alert/examples/2/index.html b/projects/demo/src/modules/components/alert/examples/2/index.html index 4f9c13a5da68..2e34ad990085 100644 --- a/projects/demo/src/modules/components/alert/examples/2/index.html +++ b/projects/demo/src/modules/components/alert/examples/2/index.html @@ -42,8 +42,6 @@ {{ money | tuiAmount: 'RUB' | async }}

-

+ `, changeDetection, }) @@ -64,7 +61,7 @@ export default class Example { .open(new PolymorpheusComponent(AlertExampleWithData), { label: 'Heading is so long that it should be shown in two lines of text', data: 237, - status: 'warning', + appearance: 'warning', autoClose: 0, }) .pipe( diff --git a/projects/demo/src/modules/components/alert/examples/5/index.ts b/projects/demo/src/modules/components/alert/examples/5/index.ts index 45de8d0805e8..83b622fa064d 100644 --- a/projects/demo/src/modules/components/alert/examples/5/index.ts +++ b/projects/demo/src/modules/components/alert/examples/5/index.ts @@ -57,11 +57,11 @@ export default class Example { private readonly notification = this.alerts .open(new PolymorpheusComponent(AlertExampleWithCustomLabel), { - label: ({status}) => - status === 'error' + label: ({appearance}) => + appearance === 'error' ? 'Error label from function' : 'Info label from function', - status: 'error', + appearance: 'error', autoClose: 0, }) .pipe(takeUntil(this.router.events)); @@ -69,7 +69,7 @@ export default class Example { private readonly notificationWithCustomLabel = this.alerts .open(new PolymorpheusComponent(AlertExampleWithCustomLabel), { label: new PolymorpheusComponent(CustomLabel), - status: 'warning', + appearance: 'warning', autoClose: 0, }) .pipe(takeUntil(this.router.events)); diff --git a/projects/demo/src/modules/components/alert/examples/6/index.html b/projects/demo/src/modules/components/alert/examples/6/index.html index 103246d5112d..ed6178f14abb 100644 --- a/projects/demo/src/modules/components/alert/examples/6/index.html +++ b/projects/demo/src/modules/components/alert/examples/6/index.html @@ -9,12 +9,9 @@ [tuiAlertOptions]="{label: 'Directive', autoClose: 0, closeable: false}" [(tuiAlert)]="show" > - This is a declarative directive alert + This is a declarative directive alert + + +
+ I am title +
I am content of the notification and I can even wrap to multiple lines.
+
+ + +
+
+
-
- + + Most boring notification + diff --git a/projects/demo/src/modules/components/notification/examples/1/index.less b/projects/demo/src/modules/components/notification/examples/1/index.less index 5c0dcba42905..23d25a3bb0a1 100644 --- a/projects/demo/src/modules/components/notification/examples/1/index.less +++ b/projects/demo/src/modules/components/notification/examples/1/index.less @@ -3,11 +3,3 @@ flex-direction: column; gap: 1rem; } - -tui-icon:last-child { - font-size: 1.5em; - margin-inline-start: 0.75rem; - color: var(--tui-text-primary); - opacity: 0.5; - float: right; -} diff --git a/projects/demo/src/modules/components/notification/examples/1/index.ts b/projects/demo/src/modules/components/notification/examples/1/index.ts index a0c3cc2724c7..7578885703f1 100644 --- a/projects/demo/src/modules/components/notification/examples/1/index.ts +++ b/projects/demo/src/modules/components/notification/examples/1/index.ts @@ -1,25 +1,14 @@ -import {CommonModule} from '@angular/common'; import {Component} from '@angular/core'; import {changeDetection} from '@demo/emulate/change-detection'; import {encapsulation} from '@demo/emulate/encapsulation'; -import {TuiHint, TuiIcon, TuiNotification} from '@taiga-ui/core'; +import {TuiButton, TuiLink, TuiNotification, TuiTitle} from '@taiga-ui/core'; @Component({ standalone: true, - imports: [CommonModule, TuiNotification, TuiIcon, TuiHint], + imports: [TuiNotification, TuiTitle, TuiButton, TuiLink], templateUrl: './index.html', styleUrls: ['./index.less'], encapsulation, changeDetection, }) -export default class Example { - protected readonly statuses = [ - 'neutral', - 'info', - 'success', - 'warning', - 'error', - ] as const; - - protected readonly sizes = ['s', 'm', 'l'] as const; -} +export default class Example {} diff --git a/projects/demo/src/modules/components/notification/examples/2/index.less b/projects/demo/src/modules/components/notification/examples/2/index.less deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/projects/demo/src/modules/components/notification/examples/2/index.ts b/projects/demo/src/modules/components/notification/examples/2/index.ts index 295e2e4aa32d..4dbc0033b7e8 100644 --- a/projects/demo/src/modules/components/notification/examples/2/index.ts +++ b/projects/demo/src/modules/components/notification/examples/2/index.ts @@ -12,7 +12,8 @@ import {TuiNotification, tuiNotificationOptionsProvider} from '@taiga-ui/core'; providers: [ tuiNotificationOptionsProvider({ icon: '@tui.circle-help', - status: 'warning', + appearance: 'warning', + size: 's', }), ], }) diff --git a/projects/demo/src/modules/components/notification/examples/3/index.html b/projects/demo/src/modules/components/notification/examples/3/index.html index 685756c1b782..3efd7bb5d2cb 100644 --- a/projects/demo/src/modules/components/notification/examples/3/index.html +++ b/projects/demo/src/modules/components/notification/examples/3/index.html @@ -1,222 +1,20 @@ -

- - Notification text - - - Notification text - - - Notification text - -

+ -
- -

- - Notification multiline long text with icons - - - Notification multiline long text with icons - - - Notification multiline long text with icons - -

- -
- -

- -

- Title -
- Notification multiline long text with icons -
- - -
- - -
- Title -
- Notification multiline long text with icons -
- - -
-
- -
- Title -
- Notification multiline long text with icons -
- - -
-
-

- -
- -

- -

- Title -
- Notification multiline long text with icons -
- - -
- - -
- Title -
- Notification multiline long text with icons -
- - -
-
- -
- Title -
- Notification multiline long text with icons -
- - -
-
-

+ + + Alerts + A notification as a toast + + diff --git a/projects/demo/src/modules/components/notification/examples/3/index.less b/projects/demo/src/modules/components/notification/examples/3/index.less index 060ac3a6b40e..23d25a3bb0a1 100644 --- a/projects/demo/src/modules/components/notification/examples/3/index.less +++ b/projects/demo/src/modules/components/notification/examples/3/index.less @@ -1,8 +1,5 @@ -.wrapper { - width: 20rem; -} - -.buttons { +:host { display: flex; - font: var(--tui-font-text-s); + flex-direction: column; + gap: 1rem; } diff --git a/projects/demo/src/modules/components/notification/examples/3/index.ts b/projects/demo/src/modules/components/notification/examples/3/index.ts index 94fd1a0edd0f..f4b03484dbe8 100644 --- a/projects/demo/src/modules/components/notification/examples/3/index.ts +++ b/projects/demo/src/modules/components/notification/examples/3/index.ts @@ -1,14 +1,18 @@ import {Component} from '@angular/core'; +import {RouterLink} from '@angular/router'; import {changeDetection} from '@demo/emulate/change-detection'; import {encapsulation} from '@demo/emulate/encapsulation'; -import {TuiButton, TuiLink, TuiNotification} from '@taiga-ui/core'; +import {DemoRoute} from '@demo/routes'; +import {TuiNotification, TuiTitle} from '@taiga-ui/core'; @Component({ standalone: true, - imports: [TuiNotification, TuiButton, TuiLink], + imports: [TuiNotification, RouterLink, TuiTitle], templateUrl: './index.html', styleUrls: ['./index.less'], encapsulation, changeDetection, }) -export default class Example {} +export default class Example { + protected readonly routes = DemoRoute; +} diff --git a/projects/demo/src/modules/components/notification/examples/import/template.md b/projects/demo/src/modules/components/notification/examples/import/template.md index a37f9ecb369b..b0f7e6a32b88 100644 --- a/projects/demo/src/modules/components/notification/examples/import/template.md +++ b/projects/demo/src/modules/components/notification/examples/import/template.md @@ -1,9 +1,3 @@ ```html - - Some content - +Some content ``` diff --git a/projects/demo/src/modules/components/notification/index.html b/projects/demo/src/modules/components/notification/index.html index d37bd708dfca..a91fed67bd0c 100644 --- a/projects/demo/src/modules/components/notification/index.html +++ b/projects/demo/src/modules/components/notification/index.html @@ -9,50 +9,11 @@ - - - - A short simple informative message - - - - - Status changes color of notification - - - Icon content. Specify - null - to hide icon. - - - Emits click on close cross. When subscribed to, close button appears. - - - - - + diff --git a/projects/demo/src/modules/components/notification/index.ts b/projects/demo/src/modules/components/notification/index.ts index 9c5cd004d961..6aadd87c9ff6 100644 --- a/projects/demo/src/modules/components/notification/index.ts +++ b/projects/demo/src/modules/components/notification/index.ts @@ -1,7 +1,6 @@ import {Component} from '@angular/core'; import {changeDetection} from '@demo/emulate/change-detection'; import {TuiDemo} from '@demo/utils'; -import type {TuiNotificationStatus} from '@taiga-ui/core'; @Component({ standalone: true, @@ -10,15 +9,5 @@ import type {TuiNotificationStatus} from '@taiga-ui/core'; changeDetection, }) export default class Page { - protected readonly examples = ['Basic', 'Options', 'Sizes']; - - protected readonly statusVariants: TuiNotificationStatus[] = [ - 'info', - 'error', - 'warning', - 'success', - 'neutral', - ]; - - protected status = this.statusVariants[0]; + protected readonly examples = ['Basic', 'Options', 'Interactive']; } diff --git a/projects/demo/src/modules/components/pdf-viewer/index.html b/projects/demo/src/modules/components/pdf-viewer/index.html index 68b55599e557..94324bdf96f5 100644 --- a/projects/demo/src/modules/components/pdf-viewer/index.html +++ b/projects/demo/src/modules/components/pdf-viewer/index.html @@ -6,14 +6,16 @@

Custom dialog to preview PDF

- - Keep in mind mobile devices do not support displaying PDFs in iframe, so you need to rely on - TUI_IS_MOBILE - token to provide suitable alternative behavior. For example, you can use third-party service - https://drive.google.com/viewerng/viewer?embedded=true&url=$YOUR_PUBLIC_PATH_TO_PDF - or your own service to render PDF in mobile iframe with - pdf.js - . + +
+ Keep in mind most mobile devices do not support displaying PDFs in iframe, so you need to rely on + TUI_IS_MOBILE + token to provide suitable alternative behavior. For example, you can use third-party service + https://drive.google.com/viewerng/viewer?embedded=true&url=$YOUR_PUBLIC_PATH_TO_PDF + or your own service to render PDF in mobile iframe with + pdf.js + . +
- Use - - Hint - - directive to enable hints with - tuiHintContent +
+ Use + + Hint + + directive to enable hints with + tuiHintContent +
diff --git a/projects/demo/src/modules/components/primitive-textfield/index.html b/projects/demo/src/modules/components/primitive-textfield/index.html index 6cac66ff0fc2..76d1a99f7e50 100644 --- a/projects/demo/src/modules/components/primitive-textfield/index.html +++ b/projects/demo/src/modules/components/primitive-textfield/index.html @@ -4,15 +4,17 @@ type="components" > - - This component is deprecated, use new - - Textfield - - instead + +
+ This component is deprecated, use new + + Textfield + + instead to build your custom textfield controls +

PrimitiveTextfield is a flexible string input that can be used as a base for complex inputs. Use it as a @@ -27,13 +29,15 @@ [content]="1 | tuiExample" > - Simplified version of - - InputPassword - +

+ Simplified version of + + InputPassword + +
Type a password @@ -46,11 +50,13 @@ [content]="2 | tuiExample: 'html,ts'" > - If you need to set some attributes or listen to events on native - input - , you can put it inside with - Textfield - directive as shown below +
+ If you need to set some attributes or listen to events on native + input + , you can put it inside with + Textfield + directive as shown below +
diff --git a/projects/demo/src/modules/components/progress-bar/examples/3/index.html b/projects/demo/src/modules/components/progress-bar/examples/3/index.html index 5d8eaeda905b..62bc28b755b1 100644 --- a/projects/demo/src/modules/components/progress-bar/examples/3/index.html +++ b/projects/demo/src/modules/components/progress-bar/examples/3/index.html @@ -1,6 +1,5 @@ - Use - overscroll-behavior: none; - CSS on your scrolling container to stop elastic scrolling on iOS +
+ Use + overscroll-behavior: none; + CSS on your scrolling container to stop elastic scrolling on iOS +
A radio component that is able to imitate native control on mobile platforms.

- Use - --tui-background-accent-2 - CSS variable to customize color of native control emulation +
+ Use + --tui-background-accent-2 + CSS variable to customize color of native control emulation +
- - Due to internal Angular implementation of radio buttons, you are required to add - name - attribute to your - input - tag, unless you are using - formControlName + +
+ Due to internal Angular implementation of radio buttons, you are required to add + name + attribute to your + input + tag, unless you are using + formControlName +
-

- Use mixin - tui-slider-ticks-labels - to arrange ticks' labels (it places them strictly below ticks). -

-

- The mixin accepts only a single argument – size of the slider ( - m - or - s - ). -

+
+

+ Use mixin + tui-slider-ticks-labels + to arrange ticks' labels (it places them strictly below ticks). +

+
+ The mixin accepts only a single argument – size of the slider ( + m + or + s + ). +
+
diff --git a/projects/demo/src/modules/components/scrollbar/index.html b/projects/demo/src/modules/components/scrollbar/index.html index 6924b39dfd73..64977bbeb561 100644 --- a/projects/demo/src/modules/components/scrollbar/index.html +++ b/projects/demo/src/modules/components/scrollbar/index.html @@ -12,9 +12,11 @@

Native scrollbar is hidden to keep native platform scroll experience

- Use - TUI_SCROLL_REF - token to get a scrollable container. For example, when working with virtual scroll. +
+ Use + TUI_SCROLL_REF + token to get a scrollable container. For example, when working with virtual scroll. +
- If you need to set some attributes or listen to events on native - input - , you can put it inside with - Textfield - directive as shown below +
+ If you need to set some attributes or listen to events on native + input + , you can put it inside with + Textfield + directive as shown below +
@@ -112,11 +114,13 @@ [content]="11 | tuiExample: 'html,ts'" > - You can enable native select on mobile devices by putting - select - inside with - tuiSelect - directive as shown below +
+ You can enable native select on mobile devices by putting + select + inside with + tuiSelect + directive as shown below +
diff --git a/projects/demo/src/modules/components/sheet/index.html b/projects/demo/src/modules/components/sheet/index.html index 8d4222cdb228..4349520e81b8 100644 --- a/projects/demo/src/modules/components/sheet/index.html +++ b/projects/demo/src/modules/components/sheet/index.html @@ -5,17 +5,19 @@ type="components" > - - If you need overlay and do not need image related functionality, it is recommended to use - - SheetDialog - - . - Sheet - component is on track to be deprecated. + +
+ If you need overlay and do not need image related functionality, it is recommended to use + + SheetDialog + + . + Sheet + component is on track to be deprecated. +
- Note - SheetHeading - component that styles the heading and adds close button if sheet is closeable. +
+ Note + SheetHeading + component that styles the heading and adds close button if sheet is closeable. +
@@ -59,14 +63,16 @@ [content]="4 | tuiExample" > - Using - - ElasticSticky - - directive. +
+ Using + + ElasticSticky + + directive. +
diff --git a/projects/demo/src/modules/components/slider/index.html b/projects/demo/src/modules/components/slider/index.html index 778c9b89c1a4..188e5f8233a9 100644 --- a/projects/demo/src/modules/components/slider/index.html +++ b/projects/demo/src/modules/components/slider/index.html @@ -53,18 +53,20 @@ [content]="3 | tuiExample" > -

- Use mixin - tui-slider-ticks-labels - to arrange ticks' labels (it places them strictly below ticks). -

-

- The mixin accepts only a single argument – size of the slider ( - m - or - s - ). -

+
+

+ Use mixin + tui-slider-ticks-labels + to arrange ticks' labels (it places them strictly below ticks). +

+
+ The mixin accepts only a single argument – size of the slider ( + m + or + s + ). +
+
diff --git a/projects/demo/src/modules/components/surface/index.html b/projects/demo/src/modules/components/surface/index.html index 246ba9453dd7..be4056ae29f4 100644 --- a/projects/demo/src/modules/components/surface/index.html +++ b/projects/demo/src/modules/components/surface/index.html @@ -27,9 +27,11 @@ *ngSwitchCase="1" class="tui-space_bottom-4" > - You can enable hover effects only on devices with pointer:
- @media (hover: hover) and (pointer: fine) + You can enable hover effects only on devices with pointer: +
+ @media (hover: hover) and (pointer: fine) +
@@ -37,34 +39,38 @@ *ngSwitchCase="2" class="tui-space_bottom-4" > - Note that - padding - and - border-radius - are not part of the surface. Take a look at - - Card - - component for that. +
+ Note that + padding + and + border-radius + are not part of the surface. Take a look at + + Card + + component for that. +
- Text should have vertical compensation to look properly aligned, either with unequal - padding - or with negative - margin - . Typical value is - 0.25rem - , smaller line-height might require - 0.125rem - instead. +
+ Text should have vertical compensation to look properly aligned, either with unequal + padding + or with negative + margin + . Typical value is + 0.25rem + , smaller line-height might require + 0.125rem + instead. +
diff --git a/projects/demo/src/modules/components/switch/index.html b/projects/demo/src/modules/components/switch/index.html index 14ed9dfcbd8e..17d532bd26e7 100644 --- a/projects/demo/src/modules/components/switch/index.html +++ b/projects/demo/src/modules/components/switch/index.html @@ -7,9 +7,11 @@ A switch component that is able to imitate native control on mobile platforms. - Use - --tui-background-accent-2 - CSS variable to customize color of native control emulation +
+ Use + --tui-background-accent-2 + CSS variable to customize color of native control emulation +
- If you use - routerLink - you must also add - routerLinkActive - directive. +
+ If you use + routerLink + you must also add + routerLinkActive + directive. +
@@ -51,7 +53,7 @@ id="customization" heading="Customization" [component]="3 | tuiComponent" - [content]="3 | tuiExample: 'html,ts'" + [content]="3 | tuiExample" /> - When there are no - TabBarItem - children, the component shows skeleton for 4 items +
+ When there are no + TabBarItem + children, the component shows skeleton for 4 items +
diff --git a/projects/demo/src/modules/components/tab-bar/index.less b/projects/demo/src/modules/components/tab-bar/index.less index 6674605c6972..ba5aa37e58b9 100644 --- a/projects/demo/src/modules/components/tab-bar/index.less +++ b/projects/demo/src/modules/components/tab-bar/index.less @@ -1,5 +1,4 @@ .bar { - display: block; width: 25rem; } diff --git a/projects/demo/src/modules/components/tabs/index.html b/projects/demo/src/modules/components/tabs/index.html index d72cc2b5f14e..e97bd955fee9 100644 --- a/projects/demo/src/modules/components/tabs/index.html +++ b/projects/demo/src/modules/components/tabs/index.html @@ -7,11 +7,13 @@

Component for creating tabs.

- If you use - routerLink - you must also add - routerLinkActive - directive. +
+ If you use + routerLink + you must also add + routerLinkActive + directive. +
- If you need to set some attributes or listen to events on native - textarea - , you can put it inside with - Textfield - directive as shown below +
+ If you need to set some attributes or listen to events on native + textarea + , you can put it inside with + Textfield + directive as shown below +
diff --git a/projects/demo/src/modules/components/textfield/index.html b/projects/demo/src/modules/components/textfield/index.html index f26228d2ba5d..812ad625366d 100644 --- a/projects/demo/src/modules/components/textfield/index.html +++ b/projects/demo/src/modules/components/textfield/index.html @@ -4,7 +4,12 @@ type="components" > - Basic textfield component to implement more complex controls based upon it. +

Basic textfield component to implement more complex controls based upon it.

+ + + Textfield based controls are in the process of being refactored. For now it is recommended to use old + components from the Legacy package + response ? this.alerts.open(wisely, { - status: 'success', + appearance: 'success', }) : this.alerts.open(poorly, { - status: 'error', + appearance: 'error', }), ), ) diff --git a/projects/demo/src/modules/directives/hint/index.html b/projects/demo/src/modules/directives/hint/index.html index d836710915ed..ab4739537383 100644 --- a/projects/demo/src/modules/directives/hint/index.html +++ b/projects/demo/src/modules/directives/hint/index.html @@ -17,11 +17,13 @@ *ngIf="index === 1" class="tui-space_bottom-4" > - Make sure - *tuiHint - directive is nested inside - tuiHint - directive so that dependency injection works properly +
+ Make sure + *tuiHint + directive is nested inside + tuiHint + directive so that dependency injection works properly +
diff --git a/projects/demo/src/modules/directives/resizer/index.html b/projects/demo/src/modules/directives/resizer/index.html index 99bbeef1a579..46ff6b8b715c 100644 --- a/projects/demo/src/modules/directives/resizer/index.html +++ b/projects/demo/src/modules/directives/resizer/index.html @@ -14,10 +14,12 @@ [fullsize]="true" > - If you need to react to the new size somehow, you can subscribe to - (tuiSizeChange) - event of type - [x: number, y: number] +
+ If you need to react to the new size somehow, you can subscribe to + (tuiSizeChange) + event of type + [x: number, y: number] +
diff --git a/projects/demo/src/modules/directives/sensitive/index.html b/projects/demo/src/modules/directives/sensitive/index.html index 55cfd5a2f1fb..3bb691d2dcba 100644 --- a/projects/demo/src/modules/directives/sensitive/index.html +++ b/projects/demo/src/modules/directives/sensitive/index.html @@ -4,12 +4,6 @@ type="directives" > - - This code is - experimental - and is a subject to change. Expect final solution to be shipped in the next major version - -

A directive that allows you to hide sensitive data under a pixel mask. This can be account balances, write-off amounts and any other content @@ -29,11 +23,13 @@ [content]="2 | tuiExample: 'html,ts'" > - Buttons have - gap - style configured for icons, avatars and other similar content. Wrap your text in - span - so it does not affect you. +

+ Buttons have + gap + style configured for icons, avatars and other similar content. Wrap your text in + span + so it does not affect you. +
diff --git a/projects/demo/src/modules/info/browsers/index.html b/projects/demo/src/modules/info/browsers/index.html index 4e0f51203525..4af62386960a 100644 --- a/projects/demo/src/modules/info/browsers/index.html +++ b/projects/demo/src/modules/info/browsers/index.html @@ -37,13 +37,15 @@

Mobile

- See our -
- browserslist config - + diff --git a/projects/demo/src/modules/markup/tables/index.html b/projects/demo/src/modules/markup/tables/index.html index 7894bceb77a4..9c49cb2893c3 100644 --- a/projects/demo/src/modules/markup/tables/index.html +++ b/projects/demo/src/modules/markup/tables/index.html @@ -12,15 +12,17 @@ - An advanced separate - @taiga-ui/table - package with interactive tables is - - here - +
+ An advanced separate + @taiga-ui/table + package with interactive tables is + + here + +

Elements

diff --git a/projects/demo/src/modules/markup/typography/index.html b/projects/demo/src/modules/markup/typography/index.html index bae0e43a7c64..926179510676 100644 --- a/projects/demo/src/modules/markup/typography/index.html +++ b/projects/demo/src/modules/markup/typography/index.html @@ -1,18 +1,20 @@ - To use classes you need to add optional - @taiga-ui/styles - package and include - @taiga-ui/styles/taiga-ui-global - in your global styles. - - Read more. - +
+ To use classes you need to add optional + @taiga-ui/styles + package and include + @taiga-ui/styles/taiga-ui-global + in your global styles. + + Read more. + +

Heading

diff --git a/projects/demo/src/modules/pipes/stringify-content/index.html b/projects/demo/src/modules/pipes/stringify-content/index.html index 06a6b1f2358e..f1c2b87e72db 100644 --- a/projects/demo/src/modules/pipes/stringify-content/index.html +++ b/projects/demo/src/modules/pipes/stringify-content/index.html @@ -17,14 +17,16 @@ [content]="1 | tuiExample: 'html,ts'" > - With - - FilterByInput - - pipe. +
+ With + + FilterByInput + + pipe. +
diff --git a/projects/demo/src/modules/pipes/stringify/index.html b/projects/demo/src/modules/pipes/stringify/index.html index 4f5baf1671d6..24c297733216 100644 --- a/projects/demo/src/modules/pipes/stringify/index.html +++ b/projects/demo/src/modules/pipes/stringify/index.html @@ -15,21 +15,23 @@ [content]="1 | tuiExample: 'html,ts'" > - With - - FilterByInput - - and - - StringifyContent - - pipes. + diff --git a/projects/demo/used-icons.ts b/projects/demo/used-icons.ts index 124897d9f4b2..1962b2f6e3a4 100644 --- a/projects/demo/used-icons.ts +++ b/projects/demo/used-icons.ts @@ -87,7 +87,6 @@ export const TUI_USED_ICONS = [ '@tui.briefcase', '@tui.code', '@tui.terminal', - '@tui.hr', '@tui.image', '@tui.map-pin', '@tui.circle-alert',