Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified packages/components/inline-edit/__screenshots__/01-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified packages/components/inline-edit/__screenshots__/01-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions packages/components/inline-edit/e2e.playwright-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,27 @@ test.describe('KbqInlineEdit', () => {
});
});

test.describe('E2eInlineEditActionButtons', () => {
const getContainer = (page: Page) => page.getByTestId('e2eInlineEditActionButtonsContainer');
const openEdit = (page: Page) => page.getByTestId('e2eInlineEditActionButtonsOpen').click();
const getSaveButton = (page: Page) =>
page.locator('.kbq-inline-edit__action-buttons .kbq-inline-edit__action-button').first().locator('button');

test('invalid state on save attempt', async ({ page }) => {
await page.goto('/E2eInlineEditActionButtons');

await openEdit(page);
await page.getByRole('textbox').clear();
await getSaveButton(page).click();

const screenshotTarget = getContainer(page);

await expect(screenshotTarget).toHaveScreenshot('07-light.png');
await e2eEnableDarkTheme(page);
await expect(screenshotTarget).toHaveScreenshot('07-dark.png');
});
});

test.describe('E2eInlineEditMenuButton', () => {
const getComponent = (page: Page) => page.getByTestId('e2eInlineEditMenuButton');
const getContainer = (page: Page) => page.getByTestId('e2eInlineEditMenuButtonContainer');
Expand Down
41 changes: 40 additions & 1 deletion packages/components/inline-edit/e2e.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, viewChildren } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { KbqButtonModule } from '@koobiq/components/button';
import { kbqInjectNativeElement } from '@koobiq/components/core';
import { KbqDropdownModule } from '@koobiq/components/dropdown';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqInputModule } from '@koobiq/components/input';
import { KbqTextareaModule } from '@koobiq/components/textarea';
import { KbqInlineEdit } from './inline-edit';
import { KbqInlineEditModule } from './module';

Expand Down Expand Up @@ -212,3 +213,41 @@ export class E2eInlineEditTruncation {}
}
})
export class E2eInlineEditMenuButton {}

@Component({
selector: 'e2e-inline-edit-action-buttons',
imports: [
ReactiveFormsModule,
KbqInlineEditModule,
KbqTextareaModule,
KbqButtonModule
],
template: `
<button kbq-button data-testid="e2eInlineEditActionButtonsOpen" (click)="textareaInlineEdit.toggleMode()">
open
</button>

<div data-testid="e2eInlineEditActionButtonsContainer" style="height: 120px">
<kbq-inline-edit #textareaInlineEdit showActions>
<div kbqInlineEditViewMode>{{ control.value || 'empty' }}</div>

<div kbqInlineEditEditMode>
@if (textareaInlineEdit.modeAsReadonly() === 'edit') {
<kbq-form-field>
<textarea kbqTextarea [formControl]="control"></textarea>
</kbq-form-field>
}
</div>
</kbq-inline-edit>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'layout-margin-top-l layout-column layout-gap-m',
style: 'max-width: 400px',
'data-testid': 'e2eInlineEditActionButtons'
}
})
export class E2eInlineEditActionButtons {
readonly control = new FormControl('Initial value', Validators.required);
}
17 changes: 11 additions & 6 deletions packages/components/inline-edit/inline-edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,17 @@

@if (showActions()) {
<div class="kbq-inline-edit__action-buttons" role="group" [@panelAnimation]>
<button kbq-button [color]="'contrast'" (click)="save($event)">
<i kbq-icon="kbq-check_16"></i>
</button>
<button kbq-button [color]="'contrast-fade'" (click)="cancel()">
<i kbq-icon="kbq-xmark_16"></i>
</button>
<div class="kbq-inline-edit__action-button">
<button kbq-button [color]="'contrast'" (click)="save($event)">
<i kbq-icon="kbq-check_16"></i>
</button>
</div>

<div class="kbq-inline-edit__action-button">
<button kbq-button [color]="'contrast-fade'" (click)="cancel()">
<i kbq-icon="kbq-xmark_16"></i>
</button>
</div>
</div>
}
</div>
Expand Down
8 changes: 3 additions & 5 deletions packages/components/inline-edit/inline-edit.scss
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,6 @@
.kbq-inline-edit__panel {
width: 100%;

.kbq-inline-edit__control-container {
border-radius: var(--kbq-size-border-radius);
}

.kbq-inline-edit__action-buttons {
position: absolute;
left: calc(-1 * var(--kbq-inline-edit-padding-horizontal));
Expand All @@ -190,7 +186,9 @@
}

.kbq-inline-edit__control-container,
.kbq-inline-edit__action-buttons > .kbq-button-icon {
.kbq-inline-edit__action-button {
box-shadow: var(--kbq-shadow-popup);
background-color: var(--kbq-background-bg);
border-radius: var(--kbq-size-border-radius);
}
}
63 changes: 34 additions & 29 deletions packages/components/inline-edit/inline-edit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
TAB
} from '@koobiq/components/core';
import { KbqDropdownModule } from '@koobiq/components/dropdown';
import { KbqFormFieldModule } from '@koobiq/components/form-field';
import { KbqIconModule } from '@koobiq/components/icon';
import { KbqInputModule } from '@koobiq/components/input';
import { KbqSelectModule } from '@koobiq/components/select';
Expand All @@ -37,6 +38,7 @@ const componentCssClasses = {
panel: '.kbq-inline-edit__panel',
focusContainer: '.kbq-inline-edit',
terminalButtons: '.kbq-inline-edit__action-buttons',
terminalButtonItem: '.kbq-inline-edit__action-button',
menuMask: '.kbq-inline-edit__menu-mask',
menu: '.kbq-inline-edit__menu',
overlay: '.cdk-overlay-pane',
Expand Down Expand Up @@ -176,9 +178,9 @@ describe('KbqInlineEdit', () => {
inlineEditDebugElement.nativeElement.click();
fixture.detectChanges();

const saveButtonHTMLElement = document.querySelector(
`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`
)!.firstElementChild as HTMLButtonElement | null;
const saveButtonHTMLElement = document
.querySelector(`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`)!
.querySelector('button') as HTMLButtonElement | null;

saveButtonHTMLElement?.click();

Expand Down Expand Up @@ -213,9 +215,9 @@ describe('KbqInlineEdit', () => {
inlineEditDebugElement.nativeElement.click();
fixture.detectChanges();

const cancelButtonHTMLElement = document.querySelector(
`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`
)!.lastElementChild as HTMLButtonElement | null;
const cancelButtonHTMLElement = document
.querySelector(`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`)!
.querySelectorAll('button')[1] as HTMLButtonElement | null;

cancelButtonHTMLElement?.click();

Expand Down Expand Up @@ -251,9 +253,9 @@ describe('KbqInlineEdit', () => {
fixture.detectChanges();
await fixture.whenStable();

const cancelButtonHTMLElement = document.querySelector(
`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`
)!.lastElementChild as HTMLButtonElement | null;
const cancelButtonHTMLElement = document
.querySelector(`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`)!
.querySelectorAll('button')[1] as HTMLButtonElement | null;

const control = getOverlayElement()!.querySelector('input');

Expand Down Expand Up @@ -333,9 +335,9 @@ describe('KbqInlineEdit', () => {
componentInstance.control.updateValueAndValidity();
fixture.detectChanges();

const saveButtonHTMLElement = document.querySelector(
`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`
)!.firstElementChild as HTMLButtonElement | null;
const saveButtonHTMLElement = document
.querySelector(`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`)!
.querySelector('button') as HTMLButtonElement | null;

saveButtonHTMLElement?.click();

Expand Down Expand Up @@ -404,9 +406,9 @@ describe('KbqInlineEdit', () => {
fixture.detectChanges();
await fixture.whenStable();

const saveButton = document.querySelector(
`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`
)!.firstElementChild as HTMLButtonElement;
const saveButton = document
.querySelector(`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`)!
.querySelector('button') as HTMLButtonElement;

saveButton.click();

Expand All @@ -430,9 +432,9 @@ describe('KbqInlineEdit', () => {
componentInstance.form.controls.firstName.updateValueAndValidity();
fixture.detectChanges();

const saveButton = document.querySelector(
`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`
)!.firstElementChild as HTMLButtonElement;
const saveButton = document
.querySelector(`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`)!
.querySelector('button') as HTMLButtonElement;

saveButton.click();

Expand All @@ -456,9 +458,9 @@ describe('KbqInlineEdit', () => {
componentInstance.form.controls.lastName.updateValueAndValidity();
fixture.detectChanges();

const saveButton = document.querySelector(
`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`
)!.firstElementChild as HTMLButtonElement;
const saveButton = document
.querySelector(`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`)!
.querySelector('button') as HTMLButtonElement;

saveButton.click();

Expand All @@ -485,9 +487,9 @@ describe('KbqInlineEdit', () => {
inputs[1].dispatchEvent(new Event('input'));
fixture.detectChanges();

const cancelButton = document.querySelector(
`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`
)!.lastElementChild as HTMLButtonElement;
const cancelButton = document
.querySelector(`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`)!
.querySelectorAll('button')[1] as HTMLButtonElement;

cancelButton.click();

Expand Down Expand Up @@ -570,10 +572,13 @@ describe('KbqInlineEdit', () => {
};

const clickSave = () => {
(
document.querySelector(`${componentCssClasses.panel} ${componentCssClasses.terminalButtons}`)!
.firstElementChild as HTMLButtonElement
).click();
const terminalButtonList = document.querySelectorAll(
`${componentCssClasses.panel} ${componentCssClasses.terminalButtonItem}`
);

if (terminalButtonList.length && terminalButtonList[0].firstElementChild instanceof HTMLButtonElement) {
terminalButtonList[0].firstElementChild.click();
}
Comment thread
NikGurev marked this conversation as resolved.
Outdated
};

it('should not show tooltip when empty string is passed and control is invalid', () => {
Expand Down Expand Up @@ -962,7 +967,7 @@ export class TestWithSelect extends BaseTestComponent {

@Component({
selector: 'name',
imports: [ReactiveFormsModule, KbqInlineEditModule, KbqTextareaModule],
imports: [ReactiveFormsModule, KbqFormFieldModule, KbqInlineEditModule, KbqTextareaModule],
template: `
<kbq-inline-edit showActions [validationTooltip]="validationTooltip()" (saved)="update()">
<div kbqInlineEditViewMode>{{ control.value }}</div>
Expand Down
8 changes: 7 additions & 1 deletion packages/e2e/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ import { E2eFileUploadDropzone, E2eFileUploadStateAndStyle } from '../components
import { E2eFilterBarStates } from '../components/filter-bar/e2e';
import { E2eFormFieldGroup, E2eFormFieldset } from '../components/form-field/e2e';
import { E2eIconStateAndStyle, E2eIconSvg } from '../components/icon/e2e';
import { E2eInlineEditMenuButton, E2eInlineEditStates, E2eInlineEditTruncation } from '../components/inline-edit/e2e';
import {
E2eInlineEditActionButtons,
E2eInlineEditMenuButton,
E2eInlineEditStates,
E2eInlineEditTruncation
} from '../components/inline-edit/e2e';
import { E2eInputStateAndStyle } from '../components/input/e2e';
import { E2eLinkStates, E2eLinkWithCaption } from '../components/link/e2e';
import { E2eListStates } from '../components/list/e2e';
Expand Down Expand Up @@ -213,6 +218,7 @@ const components = [
E2eInlineEditStates,
E2eInlineEditMenuButton,
E2eInlineEditTruncation,
E2eInlineEditActionButtons,
E2eFormHorizontal,
E2eTypographyStyles,
E2eTreeTwoLineNode,
Expand Down
Loading