From f47f52927a892318474ae9e84948ade8d9f60c5a Mon Sep 17 00:00:00 2001 From: waterplea Date: Tue, 14 May 2024 16:48:11 +0100 Subject: [PATCH 1/3] feat(addon-mobile): `DropdownMobile` add new directive Signed-off-by: waterplea --- .../dropdown-mobile.component.ts | 154 +++++++++ .../dropdown-mobile.directive.ts | 42 +++ .../dropdown-mobile.style.less | 108 ++++++ .../dropdown-mobile.template.html | 25 ++ .../directives/dropdown-mobile/index.ts | 2 + .../dropdown-mobile/ng-package.json | 5 + projects/addon-mobile/directives/index.ts | 1 + .../cdk/utils/dom/get-element-obscurers.ts | 2 +- .../data-list/option/option.component.ts | 11 +- projects/core/components/root/root.style.less | 5 + .../directives/dropdown/dropdown.component.ts | 8 +- .../core/directives/hint/hint.component.ts | 6 +- projects/demo/src/modules/app/app.routes.ts | 4 +- .../examples/5/index-change.directive.ts | 1 + .../combo-box/examples/5/index.html | 6 +- .../combo-box/examples/5/index.less | 2 +- .../components/combo-box/examples/5/index.ts | 3 + .../directives/dropdown/dropdown.component.ts | 64 ---- .../directives/dropdown/dropdown.module.ts | 68 ---- .../directives/dropdown/dropdown.style.less | 4 - .../directives/dropdown/examples/1/index.ts | 14 +- .../directives/dropdown/examples/2/index.ts | 14 +- .../directives/dropdown/examples/3/index.html | 2 +- .../directives/dropdown/examples/3/index.ts | 18 +- .../directives/dropdown/examples/4/index.html | 1 + .../directives/dropdown/examples/4/index.ts | 8 +- .../directives/dropdown/examples/5/index.ts | 16 +- .../directives/dropdown/examples/6/index.html | 76 ++++ .../directives/dropdown/examples/6/index.less | 0 .../directives/dropdown/examples/6/index.ts | 324 ++++++++++++++++++ .../import/{import-module.md => import.md} | 0 .../{insert-template.md => template.md} | 0 .../{dropdown.template.html => index.html} | 55 +-- .../src/modules/directives/dropdown/index.ts | 64 ++++ .../input-tag/input-tag.component.ts | 4 +- 35 files changed, 905 insertions(+), 212 deletions(-) create mode 100644 projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.component.ts create mode 100644 projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.directive.ts create mode 100644 projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.style.less create mode 100644 projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.template.html create mode 100644 projects/addon-mobile/directives/dropdown-mobile/index.ts create mode 100644 projects/addon-mobile/directives/dropdown-mobile/ng-package.json delete mode 100644 projects/demo/src/modules/directives/dropdown/dropdown.component.ts delete mode 100644 projects/demo/src/modules/directives/dropdown/dropdown.module.ts delete mode 100644 projects/demo/src/modules/directives/dropdown/dropdown.style.less create mode 100644 projects/demo/src/modules/directives/dropdown/examples/6/index.html create mode 100644 projects/demo/src/modules/directives/dropdown/examples/6/index.less create mode 100644 projects/demo/src/modules/directives/dropdown/examples/6/index.ts rename projects/demo/src/modules/directives/dropdown/examples/import/{import-module.md => import.md} (100%) rename projects/demo/src/modules/directives/dropdown/examples/import/{insert-template.md => template.md} (100%) rename projects/demo/src/modules/directives/dropdown/{dropdown.template.html => index.html} (72%) create mode 100644 projects/demo/src/modules/directives/dropdown/index.ts diff --git a/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.component.ts b/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.component.ts new file mode 100644 index 000000000000..bebfd1d2ce30 --- /dev/null +++ b/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.component.ts @@ -0,0 +1,154 @@ +import {DOCUMENT, NgIf} from '@angular/common'; +import type {AfterViewInit, OnDestroy} from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + inject, + ViewEncapsulation, +} from '@angular/core'; +import {IntersectionObserverModule} from '@ng-web-apis/intersection-observer'; +import {TuiKeyboardService} from '@taiga-ui/addon-mobile/services'; +import type {TuiSwipe} from '@taiga-ui/cdk'; +import { + TuiActiveZoneDirective, + tuiGetNativeFocused, + tuiInjectElement, + tuiIsElement, + tuiIsNodeIn, + tuiPx, + TuiSwipeDirective, +} from '@taiga-ui/cdk'; +import { + TUI_ANIMATIONS_SPEED, + TuiDropdownDirective, + tuiFadeIn, + tuiGetDuration, + tuiSlideInTop, +} from '@taiga-ui/core'; +import {PolymorpheusModule} from '@tinkoff/ng-polymorpheus'; + +import {TuiDropdownMobileDirective} from './dropdown-mobile.directive'; + +const GAP = 16; + +@Component({ + standalone: true, + selector: 'tui-dropdown-mobile', + imports: [IntersectionObserverModule, TuiSwipeDirective, NgIf, PolymorpheusModule], + templateUrl: './dropdown-mobile.template.html', + styleUrls: ['./dropdown-mobile.style.less'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + animations: [tuiSlideInTop, tuiFadeIn], + hostDirectives: [TuiActiveZoneDirective], + host: { + '[@tuiFadeIn]': 'animation', + '[@tuiSlideInTop]': 'animation', + '[class._sheet]': 'directive.tuiDropdownMobile', + '(document:click.silent.capture)': 'onClick($event)', + '(window>scroll.silent.capture)': 'refresh($event.currentTarget.visualViewport)', + '(visualViewport>resize.silent)': 'refresh($event.target)', + '(visualViewport>scroll.silent)': 'refresh($event.target)', + }, +}) +export class TuiDropdownMobileComponent implements OnDestroy, AfterViewInit { + private readonly el = tuiInjectElement(); + private readonly keyboard = inject(TuiKeyboardService); + private readonly doc = inject(DOCUMENT); + private readonly scrollTop = this.doc.documentElement.scrollTop; + private readonly observer = new ResizeObserver(() => + this.refresh(this.doc.defaultView!.visualViewport!), + ); + + protected readonly directive = inject(TuiDropdownMobileDirective); + protected readonly dropdown = inject(TuiDropdownDirective); + protected readonly animation = { + value: '', + params: { + start: '100vh', + duration: tuiGetDuration(inject(TUI_ANIMATIONS_SPEED)), + }, + } as const; + + constructor() { + this.observer.observe(this.dropdown.el); + this.doc.documentElement.style.setProperty('scroll-behavior', 'initial'); + } + + public ngAfterViewInit(): void { + this.el.scrollTop = this.directive.tuiDropdownMobile ? this.el.clientHeight : 0; + } + + public ngOnDestroy(): void { + this.observer.disconnect(); + this.doc.body.classList.remove('t-dropdown-mobile'); + this.doc.body.style.removeProperty('--t-root-top'); + this.doc.documentElement.scrollTop = this.scrollTop; + this.doc.documentElement.style.removeProperty('scroll-behavior'); + + if (this.focused) { + this.keyboard.hide(); + } + } + + protected onClick(event: MouseEvent): void { + if ( + !this.el.contains(event.target as Node) && + // TODO: find a better way to check if the click is inside interactive element in textfield + !( + tuiIsNodeIn(event.target as Node, 'tui-svg') || + (tuiIsElement(event.target) && event.target.tagName === 'button') + ) + ) { + event.stopPropagation(); + } + } + + protected onSwipe({direction}: TuiSwipe, el: HTMLElement): void { + if ( + direction === 'bottom' && + el.getBoundingClientRect().bottom > Number(this.doc.defaultView?.innerHeight) + ) { + this.close(); + } + } + + protected onIntersection([{isIntersecting}]: IntersectionObserverEntry[]): void { + if (isIntersecting) { + this.close(); + } + } + + protected close(): void { + this.dropdown.toggle(false); + } + + protected refresh({offsetTop, height}: VisualViewport): void { + this.doc.body.style.removeProperty('--t-root-top'); + + if ( + !this.focused || + this.directive.tuiDropdownMobile || + !this.doc.documentElement.style.getPropertyValue('scroll-behavior') + ) { + return; + } + + this.doc.documentElement.scrollTop = 0; + + const rect = this.dropdown.el.getBoundingClientRect(); + const offset = rect.height + GAP * 2; + + this.el.style.setProperty('top', tuiPx(offsetTop + offset)); + this.el.style.setProperty('height', tuiPx(height - offset)); + this.doc.body.classList.add('t-dropdown-mobile'); + this.doc.body.style.setProperty( + '--t-root-top', + tuiPx(offsetTop + GAP - rect.top), + ); + } + + private get focused(): boolean { + return this.dropdown.el.contains(tuiGetNativeFocused(this.doc)); + } +} diff --git a/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.directive.ts b/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.directive.ts new file mode 100644 index 000000000000..bd695ca9aef7 --- /dev/null +++ b/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.directive.ts @@ -0,0 +1,42 @@ +import {Directive, HostListener, inject, Input} from '@angular/core'; +import {TUI_IS_MOBILE, tuiIsHTMLElement} from '@taiga-ui/cdk'; +import {TUI_DROPDOWN_COMPONENT} from '@taiga-ui/core'; + +import {TuiDropdownMobileComponent} from './dropdown-mobile.component'; + +@Directive({ + standalone: true, + selector: '[tuiDropdownMobile]', + providers: [ + { + provide: TUI_DROPDOWN_COMPONENT, + useFactory: () => + inject(TUI_IS_MOBILE) + ? TuiDropdownMobileComponent + : inject(TUI_DROPDOWN_COMPONENT, {skipSelf: true}), + }, + ], + host: { + '[style.visibility]': '"visible"', + }, +}) +export class TuiDropdownMobileDirective { + private readonly isMobile = inject(TUI_IS_MOBILE); + + @Input() + public tuiDropdownMobile = ''; + + @HostListener('mousedown', ['$event']) + protected onMouseDown(event: MouseEvent): void { + if ( + !this.isMobile || + !tuiIsHTMLElement(event.target) || + !event.target.matches('input,textarea') + ) { + return; + } + + event.preventDefault(); + event.target.focus({preventScroll: true}); + } +} diff --git a/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.style.less b/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.style.less new file mode 100644 index 000000000000..4670c875ea93 --- /dev/null +++ b/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.style.less @@ -0,0 +1,108 @@ +@import '@taiga-ui/core/styles/taiga-ui-local'; + +tui-dropdown-mobile:not(._sheet) { + .scrollbar-hidden(); + .fullsize(fixed); + .transition(transform); + + visibility: visible !important; + transform: translate3d(0, 0, 0); + background: var(--tui-base-01); + overscroll-behavior: contain; + overflow: auto; + box-shadow: + 0 -0.5rem 0.5rem var(--tui-base-01), + 0 10rem var(--tui-base-01), + 0 20rem var(--tui-base-01), + 0 30rem var(--tui-base-01); + + &:after { + content: ''; + display: block; + height: 1px; + } + + > .t-container { + .scrollbar-hidden(); + + position: sticky; + top: 0; + height: 100%; + overflow: auto; + margin: 0 0.75rem; + touch-action: pan-y !important; + } + + [tuiDropdownButton][tuiDropdownButton] { + position: fixed; + right: 1rem; + bottom: 1rem; + display: inline-flex; + } +} + +tui-dropdown-mobile._sheet { + .fullsize(fixed, inset); + .scrollbar-hidden(); + + overflow: auto; + background: rgba(0, 0, 0, 0.75); + /* stylelint-disable-next-line */ + box-shadow: 0 -50vh 5rem 5rem rgba(0, 0, 0, 0.75); + overflow-y: scroll; + scroll-snap-type: y mandatory; + overscroll-behavior: none; + + > .t-filler { + height: 100%; + scroll-snap-stop: always; + scroll-snap-align: start; + } + + > .t-container { + display: flex; + max-height: calc(100% - 1rem); + flex-direction: column; + border-top-left-radius: 1rem; + border-top-right-radius: 1rem; + padding: 0 0.5rem; + scroll-snap-stop: always; + scroll-snap-align: start; + background: var(--tui-elevation-01); + + > .t-heading { + position: relative; + margin: 0; + padding: 2rem 0.5rem 0.75rem; + font: var(--tui-font-heading-6); + + &:before { + content: ''; + position: absolute; + left: 50%; + top: 0.75rem; + width: 2rem; + height: 0.25rem; + border-radius: 1rem; + background: var(--tui-clear-hover); + transform: translate(-50%, -50%); + } + } + + > .t-content { + .scrollbar-hidden(); + + overflow: auto; + } + } +} + +.t-dropdown-mobile { + touch-action: none; + visibility: hidden; + + * { + touch-action: inherit; + visibility: inherit; + } +} diff --git a/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.template.html b/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.template.html new file mode 100644 index 000000000000..7b70c608d9f5 --- /dev/null +++ b/projects/addon-mobile/directives/dropdown-mobile/dropdown-mobile.template.html @@ -0,0 +1,25 @@ +
+
+

+ {{ directive.tuiDropdownMobile }} +

+
+ + {{ text }} + +
+
diff --git a/projects/addon-mobile/directives/dropdown-mobile/index.ts b/projects/addon-mobile/directives/dropdown-mobile/index.ts new file mode 100644 index 000000000000..ceda1786f292 --- /dev/null +++ b/projects/addon-mobile/directives/dropdown-mobile/index.ts @@ -0,0 +1,2 @@ +export * from './dropdown-mobile.component'; +export * from './dropdown-mobile.directive'; diff --git a/projects/addon-mobile/directives/dropdown-mobile/ng-package.json b/projects/addon-mobile/directives/dropdown-mobile/ng-package.json new file mode 100644 index 000000000000..bebf62dcb5e5 --- /dev/null +++ b/projects/addon-mobile/directives/dropdown-mobile/ng-package.json @@ -0,0 +1,5 @@ +{ + "lib": { + "entryFile": "index.ts" + } +} diff --git a/projects/addon-mobile/directives/index.ts b/projects/addon-mobile/directives/index.ts index e9be0f59d7f4..00a596527fc1 100644 --- a/projects/addon-mobile/directives/index.ts +++ b/projects/addon-mobile/directives/index.ts @@ -1,3 +1,4 @@ +export * from '@taiga-ui/addon-mobile/directives/dropdown-mobile'; export * from '@taiga-ui/addon-mobile/directives/elastic-sticky'; export * from '@taiga-ui/addon-mobile/directives/ripple'; export * from '@taiga-ui/addon-mobile/directives/sidebar'; diff --git a/projects/cdk/utils/dom/get-element-obscurers.ts b/projects/cdk/utils/dom/get-element-obscurers.ts index 68247e798c9b..765a16521a9d 100644 --- a/projects/cdk/utils/dom/get-element-obscurers.ts +++ b/projects/cdk/utils/dom/get-element-obscurers.ts @@ -53,7 +53,7 @@ export function tuiGetElementObscures(element: Element): readonly Element[] | nu return nonNull; } - const filtered = nonNull.filter(el => !element.contains(el)); + const filtered = nonNull.filter(el => !element.contains(el) && !el.contains(element)); return filtered.length === 4 ? filtered : null; } diff --git a/projects/core/components/data-list/option/option.component.ts b/projects/core/components/data-list/option/option.component.ts index c1552af6c2ed..b7ecba7a832d 100644 --- a/projects/core/components/data-list/option/option.component.ts +++ b/projects/core/components/data-list/option/option.component.ts @@ -9,7 +9,7 @@ import { Input, } from '@angular/core'; import type {TuiEventWith} from '@taiga-ui/cdk'; -import {tuiInjectElement, tuiIsNativeFocused} from '@taiga-ui/cdk'; +import {TUI_IS_MOBILE, tuiInjectElement, tuiIsNativeFocused} from '@taiga-ui/cdk'; import {TuiDropdownDirective} from '@taiga-ui/core/directives/dropdown'; import type {TuiDataListHost} from '@taiga-ui/core/interfaces'; import { @@ -22,8 +22,11 @@ import {shouldCall} from '@tinkoff/ng-event-plugins'; import {TuiDataListComponent} from '../data-list.component'; -function shouldFocus({currentTarget}: TuiEventWith): boolean { - return !tuiIsNativeFocused(currentTarget); +function shouldFocus( + this: TuiOptionComponent, + {currentTarget}: TuiEventWith, +): boolean { + return !this.isMobile && !tuiIsNativeFocused(currentTarget); } // TODO: Consider all use cases for aria roles @@ -59,6 +62,8 @@ export class TuiOptionComponent implements OnDestroy { @Input() public value?: T; + public readonly isMobile = inject(TUI_IS_MOBILE); + protected readonly content = inject(TUI_OPTION_CONTENT, {optional: true}); protected readonly dropdown = inject(TuiDropdownDirective, { self: true, diff --git a/projects/core/components/root/root.style.less b/projects/core/components/root/root.style.less index 4ca177395fba..56644b34e7ff 100644 --- a/projects/core/components/root/root.style.less +++ b/projects/core/components/root/root.style.less @@ -52,4 +52,9 @@ tui-root > .t-root-scrollbar { .t-root-content { height: 100%; isolation: isolate; + transform: translateY(var(--t-root-top)); +} + +[tuiDropdownButton][tuiDropdownButton] { + display: none; } diff --git a/projects/core/directives/dropdown/dropdown.component.ts b/projects/core/directives/dropdown/dropdown.component.ts index 49b05c34aada..c4c685749f2e 100644 --- a/projects/core/directives/dropdown/dropdown.component.ts +++ b/projects/core/directives/dropdown/dropdown.component.ts @@ -57,7 +57,7 @@ export class TuiDropdownComponent implements OnInit { private readonly el = tuiInjectElement(); private readonly accessor = inject(TuiRectAccessor); private readonly win = inject(WINDOW); - private readonly viewport = inject(TuiVisualViewportService); + private readonly vvs = inject(TuiVisualViewportService); protected readonly animation = tuiToAnimationOptions(inject(TUI_ANIMATIONS_SPEED)); protected readonly options = inject(TUI_DROPDOWN_OPTIONS); @@ -69,11 +69,7 @@ export class TuiDropdownComponent implements OnInit { protected readonly sub = inject(TuiPositionService) .pipe( - map(point => - this.directive.position === 'fixed' - ? this.viewport.correct(point) - : point, - ), + map(v => (this.directive.position === 'fixed' ? this.vvs.correct(v) : v)), takeUntilDestroyed(), ) .subscribe(([top, left]) => { diff --git a/projects/core/directives/hint/hint.component.ts b/projects/core/directives/hint/hint.component.ts index dfe4885d4ea6..9125701a0650 100644 --- a/projects/core/directives/hint/hint.component.ts +++ b/projects/core/directives/hint/hint.component.ts @@ -67,7 +67,7 @@ export class TuiHintComponent { private readonly el = tuiInjectElement(); private readonly hover = inject(TuiHintHoverDirective); - private readonly visualViewportService = inject(TuiVisualViewportService); + private readonly vvs = inject(TuiVisualViewportService); private readonly viewport = inject(TUI_VIEWPORT); @HostBinding('attr.data-appearance') @@ -83,7 +83,7 @@ export class TuiHintComponent { constructor() { inject(TuiPositionService) .pipe( - map(point => this.visualViewportService.correct(point)), + map(point => this.vvs.correct(point)), takeUntilDestroyed(), ) .subscribe(([top, left]) => { @@ -124,7 +124,7 @@ export class TuiHintComponent { } const safeLeft = tuiClamp(left, GAP, viewport.width - width - GAP); - const [beakTop, beakLeft] = this.visualViewportService.correct([ + const [beakTop, beakLeft] = this.vvs.correct([ rect.top + rect.height / 2 - top, rect.left + rect.width / 2 - safeLeft, ]); diff --git a/projects/demo/src/modules/app/app.routes.ts b/projects/demo/src/modules/app/app.routes.ts index 559e34b2d820..b81365619ef4 100644 --- a/projects/demo/src/modules/app/app.routes.ts +++ b/projects/demo/src/modules/app/app.routes.ts @@ -353,9 +353,7 @@ export const ROUTES: Routes = [ }), route({ path: DemoRoute.Dropdown, - loadChildren: async () => - (await import('../directives/dropdown/dropdown.module')) - .ExampleTuiDropdownModule, + loadComponent: async () => import('../directives/dropdown'), title: 'Dropdown', }), route({ diff --git a/projects/demo/src/modules/components/combo-box/examples/5/index-change.directive.ts b/projects/demo/src/modules/components/combo-box/examples/5/index-change.directive.ts index 3fd1d0f0138a..0d4d1b219c37 100644 --- a/projects/demo/src/modules/components/combo-box/examples/5/index-change.directive.ts +++ b/projects/demo/src/modules/components/combo-box/examples/5/index-change.directive.ts @@ -2,6 +2,7 @@ import {VIRTUAL_SCROLL_STRATEGY} from '@angular/cdk/scrolling'; import {Directive, inject, Output} from '@angular/core'; @Directive({ + standalone: true, selector: '[indexChange]', }) export class IndexChangeDirective { diff --git a/projects/demo/src/modules/components/combo-box/examples/5/index.html b/projects/demo/src/modules/components/combo-box/examples/5/index.html index efe0627fe5f4..374ad14cd15b 100644 --- a/projects/demo/src/modules/components/combo-box/examples/5/index.html +++ b/projects/demo/src/modules/components/combo-box/examples/5/index.html @@ -1,12 +1,14 @@ Country + + diff --git a/projects/demo/src/modules/components/combo-box/examples/5/index.less b/projects/demo/src/modules/components/combo-box/examples/5/index.less index 54eac0a62c41..0e177bba42d4 100644 --- a/projects/demo/src/modules/components/combo-box/examples/5/index.less +++ b/projects/demo/src/modules/components/combo-box/examples/5/index.less @@ -3,5 +3,5 @@ .scroll { .scrollbar-hidden(); min-height: 64px; - max-height: 200px; + max-height: 100%; } diff --git a/projects/demo/src/modules/components/combo-box/examples/5/index.ts b/projects/demo/src/modules/components/combo-box/examples/5/index.ts index c0d930fd82ac..d988cb2fd797 100644 --- a/projects/demo/src/modules/components/combo-box/examples/5/index.ts +++ b/projects/demo/src/modules/components/combo-box/examples/5/index.ts @@ -7,6 +7,8 @@ import {TuiLetDirective} from '@taiga-ui/cdk'; import {TuiDataListModule, TuiScrollableDirective} from '@taiga-ui/core'; import {TuiComboBoxModule, TuiFilterByInputPipeModule} from '@taiga-ui/kit'; +import {IndexChangeDirective} from './index-change.directive'; + @Component({ standalone: true, selector: 'tui-combo-box-example-5', @@ -18,6 +20,7 @@ import {TuiComboBoxModule, TuiFilterByInputPipeModule} from '@taiga-ui/kit'; TuiFilterByInputPipeModule, ScrollingModule, TuiScrollableDirective, + IndexChangeDirective, ], templateUrl: './index.html', styleUrls: ['./index.less'], diff --git a/projects/demo/src/modules/directives/dropdown/dropdown.component.ts b/projects/demo/src/modules/directives/dropdown/dropdown.component.ts deleted file mode 100644 index 21afd859c5ba..000000000000 --- a/projects/demo/src/modules/directives/dropdown/dropdown.component.ts +++ /dev/null @@ -1,64 +0,0 @@ -import {Component, forwardRef} from '@angular/core'; -import {changeDetection} from '@demo/emulate/change-detection'; -import type {TuiDocExample} from '@taiga-ui/addon-doc'; - -import {AbstractExampleTuiDropdown} from '../../components/abstract/dropdown'; -import {ABSTRACT_PROPS_ACCESSOR} from '../../components/abstract/inherited-documentation/abstract-props-accessor'; - -@Component({ - selector: 'example-tui-dropdown', - templateUrl: './dropdown.template.html', - styleUrls: ['./dropdown.style.less'], - changeDetection, - providers: [ - { - provide: ABSTRACT_PROPS_ACCESSOR, - useExisting: forwardRef(() => ExampleTuiDropdownComponent), - }, - ], -}) -export class ExampleTuiDropdownComponent extends AbstractExampleTuiDropdown { - protected readonly exampleModule = import('./examples/import/import-module.md?raw'); - protected readonly exampleHtml = import('./examples/import/insert-template.md?raw'); - - protected readonly example1: TuiDocExample = { - TypeScript: import('./examples/1/index.ts?raw'), - HTML: import('./examples/1/index.html?raw'), - }; - - protected readonly example2: TuiDocExample = { - TypeScript: import('./examples/2/index.ts?raw'), - HTML: import('./examples/2/index.html?raw'), - }; - - protected readonly example3: TuiDocExample = { - TypeScript: import('./examples/3/index.ts?raw'), - HTML: import('./examples/3/index.html?raw'), - }; - - protected readonly example4: TuiDocExample = { - HTML: import('./examples/4/index.html?raw'), - LESS: import('./examples/4/index.less?raw'), - }; - - protected readonly example5: TuiDocExample = { - HTML: import('./examples/5/index.html?raw'), - LESS: import('./examples/5/index.less?raw'), - }; - - protected open = false; - - protected onClick(): void { - this.open = !this.open; - } - - protected onObscured(obscured: boolean): void { - if (obscured) { - this.open = false; - } - } - - protected onActiveZone(active: boolean): void { - this.open = active && this.open; - } -} diff --git a/projects/demo/src/modules/directives/dropdown/dropdown.module.ts b/projects/demo/src/modules/directives/dropdown/dropdown.module.ts deleted file mode 100644 index b7ce41bb0175..000000000000 --- a/projects/demo/src/modules/directives/dropdown/dropdown.module.ts +++ /dev/null @@ -1,68 +0,0 @@ -import {CommonModule} from '@angular/common'; -import {NgModule} from '@angular/core'; -import {FormsModule} from '@angular/forms'; -import {RouterModule} from '@angular/router'; -import {TuiSetupComponent} from '@demo/utils'; -import {TuiAddonDocModule, tuiGenerateRoutes} from '@taiga-ui/addon-doc'; -import {TuiActiveZoneDirective, TuiObscuredDirective} from '@taiga-ui/cdk'; -import { - TuiButtonDirective, - TuiDropdownModule, - TuiLabelDirective, - TuiLinkDirective, - TuiNotificationModule, - TuiSurfaceDirective, -} from '@taiga-ui/core'; -import { - TuiAvatarComponent, - TuiChevronDirective, - TuiInputModule, - TuiSelectModule, - TuiSwitchComponent, -} from '@taiga-ui/kit'; -import {TuiCardLargeDirective} from '@taiga-ui/layout'; -import {PolymorpheusModule} from '@tinkoff/ng-polymorpheus'; - -import {DropdownDocumentationModule} from '../../components/abstract/dropdown-documentation/dropdown-documentation.module'; -import {ExampleTuiDropdownComponent} from './dropdown.component'; -import {TuiDropdownExample1} from './examples/1'; -import {TuiDropdownExample2} from './examples/2'; -import {TuiDropdownExample3} from './examples/3'; -import {TuiDropdownExample4} from './examples/4'; -import {TuiDropdownExample5} from './examples/5'; - -@NgModule({ - imports: [ - CommonModule, - FormsModule, - PolymorpheusModule, - TuiLinkDirective, - TuiAvatarComponent, - TuiButtonDirective, - TuiDropdownModule, - TuiCardLargeDirective, - TuiSurfaceDirective, - TuiSelectModule, - TuiObscuredDirective, - TuiActiveZoneDirective, - TuiSwitchComponent, - TuiLabelDirective, - TuiInputModule, - TuiNotificationModule, - TuiAddonDocModule, - DropdownDocumentationModule, - RouterModule.forChild(tuiGenerateRoutes(ExampleTuiDropdownComponent)), - TuiChevronDirective, - TuiSetupComponent, - ], - declarations: [ - ExampleTuiDropdownComponent, - TuiDropdownExample1, - TuiDropdownExample2, - TuiDropdownExample3, - TuiDropdownExample4, - TuiDropdownExample5, - ], - exports: [ExampleTuiDropdownComponent], -}) -export class ExampleTuiDropdownModule {} diff --git a/projects/demo/src/modules/directives/dropdown/dropdown.style.less b/projects/demo/src/modules/directives/dropdown/dropdown.style.less deleted file mode 100644 index f4d8886b88b4..000000000000 --- a/projects/demo/src/modules/directives/dropdown/dropdown.style.less +++ /dev/null @@ -1,4 +0,0 @@ -.dropdown { - max-width: 20rem; - padding: 0.5rem 1.25rem; -} diff --git a/projects/demo/src/modules/directives/dropdown/examples/1/index.ts b/projects/demo/src/modules/directives/dropdown/examples/1/index.ts index 5c8a39271766..370ec84de507 100644 --- a/projects/demo/src/modules/directives/dropdown/examples/1/index.ts +++ b/projects/demo/src/modules/directives/dropdown/examples/1/index.ts @@ -1,15 +1,25 @@ import {Component} from '@angular/core'; import {changeDetection} from '@demo/emulate/change-detection'; import {encapsulation} from '@demo/emulate/encapsulation'; +import {TuiActiveZoneDirective, TuiObscuredDirective} from '@taiga-ui/cdk'; +import {TuiButtonDirective, TuiDropdownModule} from '@taiga-ui/core'; +import {TuiChevronDirective} from '@taiga-ui/kit'; @Component({ - selector: 'tui-dropdown-example-1', + standalone: true, + imports: [ + TuiDropdownModule, + TuiButtonDirective, + TuiChevronDirective, + TuiActiveZoneDirective, + TuiObscuredDirective, + ], templateUrl: './index.html', styleUrls: ['./index.less'], encapsulation, changeDetection, }) -export class TuiDropdownExample1 { +export default class ExampleComponent { protected open = false; protected onClick(): void { diff --git a/projects/demo/src/modules/directives/dropdown/examples/2/index.ts b/projects/demo/src/modules/directives/dropdown/examples/2/index.ts index 15d6596c2b0c..75e809193496 100644 --- a/projects/demo/src/modules/directives/dropdown/examples/2/index.ts +++ b/projects/demo/src/modules/directives/dropdown/examples/2/index.ts @@ -1,16 +1,26 @@ import {Component} from '@angular/core'; +import {FormsModule} from '@angular/forms'; import {changeDetection} from '@demo/emulate/change-detection'; import {encapsulation} from '@demo/emulate/encapsulation'; import {assets} from '@demo/utils'; +import {TuiDropdownModule, TuiLinkDirective} from '@taiga-ui/core'; +import {TuiAvatarComponent, TuiSwitchComponent} from '@taiga-ui/kit'; @Component({ - selector: 'tui-dropdown-example-2', + standalone: true, + imports: [ + TuiDropdownModule, + TuiSwitchComponent, + FormsModule, + TuiLinkDirective, + TuiAvatarComponent, + ], templateUrl: './index.html', styleUrls: ['./index.less'], encapsulation, changeDetection, }) -export class TuiDropdownExample2 { +export default class ExampleComponent { protected open = false; protected avatarUrl = assets`/images/avatar.jpg`; } diff --git a/projects/demo/src/modules/directives/dropdown/examples/3/index.html b/projects/demo/src/modules/directives/dropdown/examples/3/index.html index 483dce727fac..717519d35c88 100644 --- a/projects/demo/src/modules/directives/dropdown/examples/3/index.html +++ b/projects/demo/src/modules/directives/dropdown/examples/3/index.html @@ -16,7 +16,7 @@