Skip to content

Commit

Permalink
fix(legacy): InputDate{Range|Time} + input[tuiTextfieldLegacy] + …
Browse files Browse the repository at this point in the history
…`tuiTextfieldFiller` has CD problems (#9932)
  • Loading branch information
nsbarsukov authored Dec 9, 2024
1 parent b6dba0c commit 026d13c
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -291,5 +291,38 @@ test.describe('InputDateRange', () => {
'08-calendar-correct-selected-period-after-close-open.png',
);
});

test.describe('with `input[tuiTextfieldLegacy]` inside', () => {
test('filler has no change detection problems', async () => {
const example = documentationPage.getExample('#base');
const inputDateRange = new TuiInputDateRangePO(
example.locator('tui-input-date-range'),
);

/**
* To ensure that example is not changed and
* still contains InputDateRange with projected <input tuiTextfieldLegacy>
*/
await expect(
inputDateRange.host.locator('input[tuiTextfieldLegacy]'),
).toBeAttached();

await inputDateRange.textfield.focus();

await expect(inputDateRange.host).toHaveScreenshot(
'12-backspace-pressed-0-times.png',
);

for (let i = 1; i <= 16; i++) {
await inputDateRange.textfield.press('Backspace');

await expect(inputDateRange.host).toHaveScreenshot(
`12-backspace-pressed-${i}-times.png`,
);
}

await expect(inputDateRange.textfield).toHaveValue('');
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -312,24 +312,17 @@ test.describe('InputDateTime', () => {
});

test.describe('Examples', () => {
let example!: Locator;
let documentationPage!: TuiDocumentationPagePO;
let inputDateTime!: TuiInputDateTimePO;

test.beforeEach(async ({page}) => {
await tuiGoto(page, DemoRoute.InputDateTime);

documentationPage = new TuiDocumentationPagePO(page);
example = documentationPage.apiPageExample;

inputDateTime = new TuiInputDateTimePO(
example.locator('tui-input-date-time'),
);
});

test('With validator: enter incomplete date -> validator error', async () => {
example = documentationPage.getExample('#with-validator');
inputDateTime = new TuiInputDateTimePO(
const example = documentationPage.getExample('#with-validator');
const inputDateTime = new TuiInputDateTimePO(
example.locator('tui-input-date-time'),
);

Expand All @@ -343,5 +336,38 @@ test.describe('InputDateTime', () => {
{animations: 'allow'},
);
});

test.describe('with `input[tuiTextfieldLegacy]` inside', () => {
test('filler has no change detection problems', async () => {
const example = documentationPage.getExample('#base');
const inputDateTime = new TuiInputDateTimePO(
example.locator('tui-input-date-time'),
);

/**
* To ensure that example is not changed and
* still contains InputDateTime with projected <input tuiTextfieldLegacy>
*/
await expect(
inputDateTime.host.locator('input[tuiTextfieldLegacy]'),
).toBeAttached();

await inputDateTime.textfield.focus();

await expect(inputDateTime.host).toHaveScreenshot(
'05-backspace-pressed-0-times.png',
);

for (let i = 1; i <= 8; i++) {
await inputDateTime.textfield.press('Backspace');

await expect(inputDateTime.host).toHaveScreenshot(
`05-backspace-pressed-${i}-times.png`,
);
}

await expect(inputDateTime.textfield).toHaveValue('');
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,25 @@ import {TUI_PLAYWRIGHT_MOBILE_USER_AGENT} from '../../../playwright.options';

test.describe('InputDate', () => {
test.describe('Examples', () => {
let documentationPage!: TuiDocumentationPagePO;

test.use({
viewport: {
width: 450,
height: 650,
},
});

test('correct filler display for size', async ({page}) => {
test.beforeEach(async ({page}) => {
await tuiGoto(page, DemoRoute.InputDate);

const api = new TuiDocumentationPagePO(page);
const example = api.getExample('#sizes');
documentationPage = new TuiDocumentationPagePO(page);
});

await api.prepareBeforeScreenshot();
test('correct filler display for size', async ({page}) => {
const example = documentationPage.getExample('#sizes');

await documentationPage.prepareBeforeScreenshot();

for (const size of ['s', 'm', 'l']) {
const input = example
Expand All @@ -52,6 +57,37 @@ test.describe('InputDate', () => {
await expect(page).toHaveScreenshot(`01-04-input-date-${size}.png`);
}
});

test.describe('with `input[tuiTextfieldLegacy]` inside', () => {
test('filler has no change detection problems', async () => {
const example = documentationPage.getExample('#date-localization');
const inputDate = new TuiInputDatePO(example.locator('tui-input-date'));

/**
* To ensure that example is not changed and
* still contains InputDate with projected <input tuiTextfieldLegacy>
*/
await expect(
inputDate.host.locator('input[tuiTextfieldLegacy]'),
).toBeAttached();

await inputDate.textfield.focus();

await expect(inputDate.host).toHaveScreenshot(
'14-backspace-pressed-0-times.png',
);

for (let i = 1; i <= 8; i++) {
await inputDate.textfield.press('Backspace');

await expect(inputDate.host).toHaveScreenshot(
`14-backspace-pressed-${i}-times.png`,
);
}

await expect(inputDate.textfield).toHaveValue('');
});
});
});

test.describe('API', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class TuiInputDateRangePO {
'[automation-id="tui-calendar-range__menu"]',
);

constructor(private readonly host: Locator) {}
constructor(public readonly host: Locator) {}

public async getItems(): Promise<Locator[]> {
const dataList = this.calendar.locator(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export class TuiInputDatePO {
public readonly textfield: Locator = this.host.getByRole('textbox');
public readonly calendar: Locator = this.host.page().locator('tui-calendar');

constructor(private readonly host: Locator) {}
constructor(public readonly host: Locator) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Component,
inject,
Input,
signal,
ViewChild,
} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
Expand Down Expand Up @@ -86,6 +87,7 @@ export class TuiInputDateRangeComponent
private readonly mobileCalendar = inject(TUI_MOBILE_CALENDAR, {optional: true});
private readonly options = inject(TUI_INPUT_DATE_OPTIONS);
private readonly textfieldSize = inject(TUI_TEXTFIELD_SIZE);
private readonly nativeValue = signal('');

protected readonly dateTexts$ = inject(TUI_DATE_TEXTS);
protected override readonly valueTransformer = inject(
Expand Down Expand Up @@ -160,7 +162,7 @@ export class TuiInputDateRangeComponent

return value
? value.getFormattedDayRange(this.dateFormat.mode, this.dateFormat.separator)
: nativeValue;
: nativeValue();
}

public get size(): TuiSizeL | TuiSizeS {
Expand All @@ -174,6 +176,8 @@ export class TuiInputDateRangeComponent
}

public onValueChange(value: string): void {
this.nativeValue.set(value);

if (this.control) {
this.control.updateValueAndValidity({emitEvent: false});
}
Expand All @@ -183,7 +187,7 @@ export class TuiInputDateRangeComponent
}

if (this.activePeriod) {
this.nativeValue = '';
this.nativeValue.set('');
}

this.value =
Expand All @@ -201,15 +205,15 @@ export class TuiInputDateRangeComponent
this.focusInput();

if (!range) {
this.nativeValue = '';
this.nativeValue.set('');
}

this.value = range;
}

public override writeValue(value: TuiDayRange | null): void {
super.writeValue(value);
this.nativeValue = value ? this.computedValue : '';
this.nativeValue.set(value ? this.computedValue : '');
}

protected get computedMobile(): boolean {
Expand Down Expand Up @@ -269,16 +273,6 @@ export class TuiInputDateRangeComponent
return null;
}

protected get nativeValue(): string {
return this.nativeFocusableElement?.value || '';
}

protected set nativeValue(value: string) {
if (this.nativeFocusableElement) {
this.nativeFocusableElement.value = value;
}
}

protected getComputedRangeFiller(dateFiller: string): string {
return this.activePeriod ? '' : this.getDateRangeFiller(dateFiller);
}
Expand All @@ -299,12 +293,12 @@ export class TuiInputDateRangeComponent
if (
!focused &&
!this.itemSelected &&
(this.nativeValue.length === DATE_FILLER_LENGTH ||
this.nativeValue.length ===
(this.nativeValue().length === DATE_FILLER_LENGTH ||
this.nativeValue().length ===
DATE_FILLER_LENGTH + RANGE_SEPARATOR_CHAR.length)
) {
this.value = TuiDayRange.normalizeParse(
this.nativeValue,
this.nativeValue(),
this.dateFormat.mode,
);
}
Expand All @@ -318,7 +312,7 @@ export class TuiInputDateRangeComponent
}

private get itemSelected(): boolean {
return this.items.findIndex((item) => String(item) === this.nativeValue) !== -1;
return this.items.findIndex((item) => String(item) === this.nativeValue()) !== -1;
}

@tuiPure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,17 @@ describe('InputDateRangeComponent', () => {
});

it('correctly sets stringify selected range via calendar', async () => {
inputPO.sendTextAndBlur('12/01/2021-02/14/2022');
inputPO.sendText('12/01/2021-02/14/2022');
/**
* TODO
* Uncomment me to see [TypeError: Cannot read properties of undefined (reading 'addEventListener')]
* ___
* Stacktrace says that error happens inside `TUI_ACTIVE_ELEMENT`.
* Utility `tuiGetDocumentOrShadowRoot` returns `undefined`.
*/
// inputPO.blur();

await fixture.whenStable();

clickOnTextfield();

Expand Down Expand Up @@ -535,17 +545,19 @@ describe('InputDateRangeComponent', () => {
expect(inputPO.value).toBe('12.09.2021 – 18.10.2021');
});

it('transforms value which was programmatically patched', () => {
testComponent.control.patchValue([
new Date(1922, 11, 30),
new Date(1991, 11, 26),
]);
it('transforms value which was programmatically patched', async () => {
const newDateRange = [new Date(1922, 11, 30), new Date(1991, 11, 26)] as [
Date,
Date,
];

testComponent.control.patchValue(newDateRange);

fixture.detectChanges();
await fixture.whenStable();

expect(inputPO.value).toBe('30.12.1922 – 26.12.1991');
expect(testComponent.control.value).toEqual([
new Date(1922, 11, 30),
new Date(1991, 11, 26),
]);
expect(testComponent.control.value).toEqual(newDateRange);
});
});

Expand Down
Loading

0 comments on commit 026d13c

Please sign in to comment.