Skip to content

Commit

Permalink
chore(demo): add example about viewport and dropdown (#5683)
Browse files Browse the repository at this point in the history
  • Loading branch information
splincode authored Oct 20, 2023
1 parent 1ecdd83 commit 53d31a8
Show file tree
Hide file tree
Showing 14 changed files with 313 additions and 3 deletions.
2 changes: 1 addition & 1 deletion projects/cdk/abstract/portal-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export abstract class AbstractTuiPortalHostComponent {

constructor(
@Inject(INJECTOR) private readonly injector: Injector,
@Inject(ElementRef) private readonly el: ElementRef<HTMLElement>,
@Inject(ElementRef) protected readonly el: ElementRef<HTMLElement>,
@Inject(AbstractTuiPortalService) portalService: AbstractTuiPortalService,
) {
portalService.attach(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export class TuiDropdownPositionDirective extends TuiPositionAccessor {
const {minHeight, align, direction, offset} = this.options;
const viewport = {
top: viewportRect.top - offset,
bottom: viewportRect.bottom - offset,
bottom: viewportRect.bottom + offset,
right: viewportRect.right - offset,
left: viewportRect.left - offset,
left: viewportRect.left + offset,
} as const;
const previous = this.previous || direction || 'bottom';
const available = {
Expand Down
9 changes: 9 additions & 0 deletions projects/demo/src/modules/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,15 @@ export const ROUTES: Routes = [
title: `Portals`,
},
},
{
path: `viewport`,
loadChildren: async () =>
(await import(`../customization/viewport/viewport.module`))
.ExampleTuiViewportModule,
data: {
title: `Viewport`,
},
},
// COMPONENTS
{
path: `components/accordion`,
Expand Down
6 changes: 6 additions & 0 deletions projects/demo/src/modules/app/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,12 @@ export const pages: TuiDocPages = [
keywords: `portal, custom, theme, style`,
route: `/portals`,
},
{
section: `Customization`,
title: `Viewport`,
keywords: `viewport, вьюпорт, портал, контекст, выпадашка, дропдаун, portal, dropdown`,
route: `/viewport`,
},
// Tools
{
section: `Tools`,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<div class="dropdowns">
<div
tuiDropdown="1"
tuiDropdownHover
class="t1"
></div>
<div
tuiDropdown="3"
tuiDropdownHover
class="t2"
></div>
<div
tuiDropdown="2"
tuiDropdownHover
class="t3"
></div>
<div
tuiDropdown="4"
tuiDropdownHover
class="t4"
></div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@import 'taiga-ui-local';

.dropdowns {
position: relative;
height: 18.75rem;
width: 50%;
display: block;
resize: both;
overflow: auto;
outline: 0.125rem dotted var(--tui-base-04);

@media @tui-tablet {
width: 100%;
}
}

.t1,
.t2,
.t3,
.t4 {
position: absolute;
width: 3.125rem;
height: 3.125rem;
background: var(--tui-primary);
}

.t1 {
top: 0.625rem;
left: 0.625rem;
}

.t2 {
top: 0.625rem;
right: 0.625rem;
}

.t3 {
right: 0.625rem;
bottom: 0.625rem;
}

.t4 {
left: 0.625rem;
bottom: 0.625rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {Component, ElementRef, Inject} from '@angular/core';
import {changeDetection} from '@demo/emulate/change-detection';
import {encapsulation} from '@demo/emulate/encapsulation';
import {tuiAsViewport, TuiRectAccessor} from '@taiga-ui/core';

@Component({
selector: 'tui-viewport-example-1',
templateUrl: './index.html',
styleUrls: ['./index.less'],
providers: [tuiAsViewport(TuiViewportExample1)],
changeDetection,
encapsulation,
})
export class TuiViewportExample1 extends TuiRectAccessor {
readonly type = 'viewport';

constructor(@Inject(ElementRef) private readonly el: ElementRef<HTMLElement>) {
super();
}

getClientRect(): ClientRect {
return this.el.nativeElement.getBoundingClientRect();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<div
portalHost
class="dropdowns"
>
<div
tuiDropdownHover
class="t1"
[tuiDropdown]="dropdown"
></div>
<div
tuiDropdownHover
class="t2"
[tuiDropdown]="dropdown"
></div>
<div
tuiDropdownHover
class="t3"
[tuiDropdown]="dropdown"
></div>
<div
tuiDropdownHover
class="t4"
[tuiDropdown]="dropdown"
></div>
</div>

<ng-template #dropdown>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's
standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make
a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting,
remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions
of Lorem Ipsum.
</p>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Component} from '@angular/core';
import {changeDetection} from '@demo/emulate/change-detection';
import {encapsulation} from '@demo/emulate/encapsulation';

@Component({
selector: 'tui-viewport-example-2',
templateUrl: './index.html',
styleUrls: ['../1/index.less'],
changeDetection,
encapsulation,
})
export class TuiViewportExample2 {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {
AbstractTuiPortalHostComponent,
AbstractTuiPortalService,
TuiDropdownPortalService,
} from '@taiga-ui/cdk';
import {tuiAsViewport, TuiRectAccessor} from '@taiga-ui/core';

@Component({
selector: `[portalHost]`,
template: `
<ng-content></ng-content>
<ng-container #viewContainer></ng-container>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
TuiDropdownPortalService,
{
provide: AbstractTuiPortalService,
useExisting: TuiDropdownPortalService,
},
{
provide: AbstractTuiPortalHostComponent,
useExisting: PortalHost,
},
tuiAsViewport(PortalHost),
],
})
export class PortalHost
extends AbstractTuiPortalHostComponent
implements TuiRectAccessor
{
readonly type = `viewport`;

getClientRect(): ClientRect {
return this.el.nativeElement.getBoundingClientRect();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
```ts
import {Component} from '@angular/core';
import {TUI_VIEWPORT} from '@taiga-ui/core';

@Component({
// ...
providers: [
{
provide: TUI_VIEWPORT,
useFactory: () => {
const win = inject(WINDOW);

return {
type: `viewport`,
getClientRect() {
return {
top: 0,
left: 0,
right: win.innerWidth,
bottom: win.innerHeight,
width: win.innerWidth,
height: win.innerHeight,
};
},
};
},
},
],
})
export class MyComponent {}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Component} from '@angular/core';
import {changeDetection} from '@demo/emulate/change-detection';
import {TuiDocExample} from '@taiga-ui/addon-doc';

@Component({
selector: 'example-tui-viewport',
templateUrl: './viewport.template.html',
changeDetection,
})
export class ExampleTuiViewportComponent {
readonly providers = import('./examples/import/providers.md?raw');

readonly example1: TuiDocExample = {
TypeScript: import('./examples/1/index.ts?raw'),
HTML: import('./examples/1/index.html?raw'),
LESS: import('./examples/1/index.less?raw'),
};

readonly example2: TuiDocExample = {
TypeScript: import('./examples/2/index.ts?raw'),
HTML: import('./examples/2/index.html?raw'),
LESS: import('./examples/1/index.less?raw'), // shared
'portal-host.component.ts': import('./examples/2/portal-host.ts?raw'),
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {NgModule} from '@angular/core';
import {TuiAddonDocModule, tuiGetDocModules} from '@taiga-ui/addon-doc';
import {TuiDropdownModule} from '@taiga-ui/core';

import {TuiViewportExample1} from './examples/1';
import {TuiViewportExample2} from './examples/2';
import {PortalHost} from './examples/2/portal-host';
import {ExampleTuiViewportComponent} from './viewport.component';

@NgModule({
imports: [
TuiDropdownModule,
TuiAddonDocModule,
tuiGetDocModules(ExampleTuiViewportComponent),
],
declarations: [
ExampleTuiViewportComponent,
TuiViewportExample1,
TuiViewportExample2,
PortalHost,
],
})
export class ExampleTuiViewportModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<tui-doc-page
header="Viewport"
package="CORE"
>
<ng-template pageTab>
<p>
<code>TUI_VIEWPORT</code>
- define the area relative to which the position constraints will be calculated. Also you can use
<code>tuiAsViewport</code>
helper instead of token.
</p>

<tui-doc-example
id="base"
description="Here we just limit viewport relative to which the position of the dropdown will be calculated"
heading="Dropdown"
class="dropdown"
[content]="example1"
[fullsize]="true"
>
<tui-viewport-example-1></tui-viewport-example-1>
</tui-doc-example>

<tui-doc-example
id="portal"
description="If you want your dropdown to open in specific viewport in DOM of your web application, then you need to create your own portal"
heading="Dropdown with custom portal"
class="dropdown"
[content]="example2"
[fullsize]="true"
>
<tui-viewport-example-2></tui-viewport-example-2>
</tui-doc-example>
</ng-template>

<ng-template pageTab="Setup">
<tui-doc-code [code]="providers"></tui-doc-code>
</ng-template>
</tui-doc-page>

0 comments on commit 53d31a8

Please sign in to comment.