Skip to content

Commit

Permalink
feat(addon-doc): render page tabs as soon as possible
Browse files Browse the repository at this point in the history
  • Loading branch information
splincode committed Oct 3, 2024
1 parent 1b732e8 commit 2a3e1b8
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 27 deletions.
2 changes: 1 addition & 1 deletion projects/addon-doc/components/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
class="t-wrapper"
[attr.tuiTheme]="theme()"
[class.t-wrapper_transparent]="!opaque"
[style.visibility]="rendered() ? 'visible' : 'hidden'"
>
<div class="t-content">
<div
#content
id="demo-content"
>
<form
*ngIf="testForm"
class="t-form"
[formGroup]="testForm"
>
Expand Down
24 changes: 17 additions & 7 deletions projects/addon-doc/components/demo/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {JsonPipe, Location, NgIf, NgTemplateOutlet} from '@angular/common';
import {JsonPipe, Location, NgTemplateOutlet} from '@angular/common';
import type {ElementRef, OnInit} from '@angular/core';
import {
ChangeDetectionStrategy,
Component,
computed,
ContentChild,
DestroyRef,
inject,
Input,
signal,
Expand All @@ -13,7 +14,7 @@ import {
} from '@angular/core';
import {takeUntilDestroyed, toObservable} from '@angular/core/rxjs-interop';
import type {AbstractControl} from '@angular/forms';
import {FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {FormControl, FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms';
import type {Params, UrlTree} from '@angular/router';
import {UrlSerializer} from '@angular/router';
import {TUI_DOC_DEMO_TEXTS, TUI_DOC_URL_STATE_HANDLER} from '@taiga-ui/addon-doc/tokens';
Expand All @@ -32,7 +33,7 @@ import {TuiSwitch} from '@taiga-ui/kit/components/switch';
import {TuiChevron} from '@taiga-ui/kit/directives/chevron';
import {TuiSelectModule} from '@taiga-ui/legacy/components/select';
import {TuiTextfieldControllerModule} from '@taiga-ui/legacy/directives/textfield-controller';
import {skip} from 'rxjs';
import {skip, timer} from 'rxjs';

const MIN_WIDTH = 160;

Expand All @@ -42,7 +43,6 @@ const MIN_WIDTH = 160;
imports: [
FormsModule,
JsonPipe,
NgIf,
NgTemplateOutlet,
ReactiveFormsModule,
TuiButton,
Expand Down Expand Up @@ -76,6 +76,7 @@ export class TuiDocDemo implements OnInit {
private readonly resizer?: ElementRef<HTMLElement>;

private readonly el = tuiInjectElement();
private readonly destroyRef = inject(DestroyRef);
private readonly locationRef = inject(Location);
private readonly urlSerializer = inject(UrlSerializer);
private readonly urlStateHandler = inject(TUI_DOC_URL_STATE_HANDLER);
Expand All @@ -84,6 +85,8 @@ export class TuiDocDemo implements OnInit {
@ContentChild(TemplateRef)
protected readonly template: TemplateRef<Record<string, unknown>> | null = null;

protected readonly rendered = signal(false);

protected theme = computed(() => (this.dark() ? 'dark' : 'light'));

protected dark = signal(
Expand All @@ -94,7 +97,9 @@ export class TuiDocDemo implements OnInit {
.pipe(skip(1), takeUntilDestroyed())
.subscribe((mode) => this.onModeChange(mode));

protected testForm?: FormGroup;
protected testForm = new FormGroup<{testValue: AbstractControl}>({
testValue: new FormControl(null),
});

protected readonly updateOnVariants = ['change', 'blur', 'submit'] as const;

Expand All @@ -113,8 +118,13 @@ export class TuiDocDemo implements OnInit {
public sticky = true;

public ngOnInit(): void {
this.createForm();
this.updateWidth(this.sandboxWidth + this.delta);
timer(0)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.createForm();
this.updateWidth(this.sandboxWidth + this.delta);
this.rendered.set(true);
});
}

protected onResize(): void {
Expand Down
9 changes: 4 additions & 5 deletions projects/addon-doc/components/page/page.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,9 @@ <h1 class="t-title">
class="t-see-also"
[seeAlso]="seeAlso"
/>
<ng-container *ngFor="let tab of tabConnectors; index as index">
<ng-container
*ngIf="index === activeItemIndex"
[ngTemplateOutlet]="tab.template"
/>
<ng-container *ngFor="let tab of tabConnectors; let index = index">
<div [style.display]="index === activeItemIndex ? 'block' : 'none'">
<ng-container [ngTemplateOutlet]="tab.template" />
</div>
</ng-container>
</div>
30 changes: 25 additions & 5 deletions projects/demo-playwright/tests/core/dialogs/dialogs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ test.describe('Dialogs', () => {
`${DemoRoute.Dialog}/API?closeable=true&dismissible=false`,
);

await page.locator('tui-doc-page button[data-appearance="primary"]').click();
await page
.locator('button[data-appearance="primary"]:visible')
.getByText('Show')
.click();

await page.mouse.click(100, 100);

await expect(page.locator('tui-dialog')).toHaveCount(1);
Expand All @@ -162,7 +166,11 @@ test.describe('Dialogs', () => {
`${DemoRoute.Dialog}/API?closeable=false&dismissible=true`,
);

await page.locator('tui-doc-page button[data-appearance="primary"]').click();
await page
.locator('button[data-appearance="primary"]:visible')
.getByText('Show')
.click();

await page.mouse.click(100, 100);

await expect(page.locator('tui-dialog')).toHaveCount(0);
Expand All @@ -174,7 +182,11 @@ test.describe('Dialogs', () => {
`${DemoRoute.Dialog}/API?closeable=true&dismissible=false`,
);

await page.locator('tui-doc-page button[data-appearance="primary"]').click();
await page
.locator('button[data-appearance="primary"]:visible')
.getByText('Show')
.click();

await page.mouse.click(100, 100);

await expect(page.locator('tui-dialog')).toHaveCount(1);
Expand All @@ -190,7 +202,11 @@ test.describe('Dialogs', () => {
`${DemoRoute.Dialog}/API?size=fullscreen&dismissible=true`,
);

await page.locator('tui-doc-page button[data-appearance="primary"]').click();
await page
.locator('button[data-appearance="primary"]:visible')
.getByText('Show')
.click();

await page.mouse.click(100, 100);

await expect(page.locator('tui-dialog')).toHaveCount(1);
Expand All @@ -205,7 +221,11 @@ test.describe('Dialogs', () => {
`${DemoRoute.Dialog}/API?size=fullscreen&dismissible=true`,
);

await page.locator('tui-doc-page button[data-appearance="primary"]').click();
await page
.locator('button[data-appearance="primary"]:visible')
.getByText('Show')
.click();

await page.mouse.click(100, 100);

await expect(page.locator('tui-dialog')).toHaveCount(1);
Expand Down
17 changes: 15 additions & 2 deletions projects/demo-playwright/tests/demo/demo.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import {TuiDocumentationPagePO, tuiGoto, tuiMockImages} from '@demo-playwright/utils';
import {
TuiDocumentationPagePO,
tuiGoto,
tuiMockImages,
waitStableState,
} from '@demo-playwright/utils';
import type {Locator} from '@playwright/test';
import {expect, test} from '@playwright/test';

import {tuiIsFlakyExample} from './is-flaky-examples';
Expand All @@ -24,9 +30,16 @@ test.describe('Demo', () => {
}
}).toPass();

const visibleExamples: Locator[] = [];
const examples = await page.getByTestId('tui-doc-example').all();

for (const [i, example] of examples.entries()) {
for (const example of examples) {
if (await waitStableState(example)) {
visibleExamples.push(example);
}
}

for (const [i, example] of visibleExamples.entries()) {
if (tuiIsFlakyExample(path, i)) {
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test.describe('Routable', () => {

await expect(page).toHaveURL(/\/dialog\/lazy-routable\/path\/to\/dialog$/);

await page.locator('[automation-id="tui-dialog__close"]').click();
await page.locator('[automation-id="tui-dialog__close"]').nth(1).click();

await expect(page).toHaveURL(/\/dialog\/lazy-routable$/);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {waitStableState} from '../wait-stable-state';

export class TuiDocumentationApiPagePO {
public readonly pageExamples: Locator = this.page.locator('tui-doc-example');
public readonly apiPageExample: Locator = this.page.locator('#demo-content');
public readonly apiPageExample: Locator = this.page.locator('#demo-content:visible');

constructor(protected readonly page: Page) {}

Expand Down
10 changes: 7 additions & 3 deletions projects/demo-playwright/utils/wait-stable-state.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {Locator} from '@playwright/test';

export async function waitStableState(locator: Locator): Promise<void> {
export async function waitStableState(locator: Locator): Promise<boolean> {
try {
const handle = await locator.elementHandle();

Expand All @@ -12,6 +12,10 @@ export async function waitStableState(locator: Locator): Promise<void> {

// https://playwright.dev/docs/actionability#visible
// Element is considered visible when it has non-empty bounding box
await handle?.waitForElementState('visible');
} catch {}
await handle?.waitForElementState('visible', {timeout: 1000});

return true;
} catch {
return false;
}
}
2 changes: 1 addition & 1 deletion projects/demo/src/modules/components/tabs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@

<ng-template pageTab="Routing">
<tui-doc-example [content]="8 | tuiExample: 'html,ts'">
<router-outlet />
<router-outlet *ngIf="path.url.endsWith('Routing')" />
</tui-doc-example>
</ng-template>
</tui-doc-page>
5 changes: 4 additions & 1 deletion projects/demo/src/modules/components/tabs/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Component} from '@angular/core';
import {Component, inject} from '@angular/core';
import {Router} from '@angular/router';
import {changeDetection} from '@demo/emulate/change-detection';
import {TuiDemo} from '@demo/utils';
import {tuiDocExampleOptionsProvider} from '@taiga-ui/addon-doc';
Expand All @@ -14,6 +15,8 @@ import {TuiTabs} from '@taiga-ui/kit';
providers: [tuiDocExampleOptionsProvider({fullsize: true})],
})
export default class Page {
protected readonly path = inject(Router);

protected buttons = ['Button 1', 'Button 2', 'Button 3', 'Button 4'];

protected readonly moreContentVariants = ['', 'And more'];
Expand Down

0 comments on commit 2a3e1b8

Please sign in to comment.