Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dial-pad): prevent focus loss after removal of delete button (VIV-2126) #1912

Merged
merged 29 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0d49cde
fix(dial-pad): prevent multiple events from firing
Sep 18, 2024
20c0006
Refactor
Sep 18, 2024
21c127a
Lint
Sep 18, 2024
22193ff
value sync
Sep 18, 2024
5b66bc9
Emit change on delete press
Sep 18, 2024
d26360a
Prevent multiple events
Sep 19, 2024
e9f8619
Lint
Sep 19, 2024
7d2f9cd
Refactor tests
Sep 19, 2024
2d42392
Refactor template
Sep 19, 2024
8847d18
Merge branch 'main' into VIV-2065-dial-pad-events-leak
YonatanKra Sep 19, 2024
921eb46
Update docs
Sep 19, 2024
2e2c428
Merge branch 'main' into VIV-2065-dial-pad-events-leak
YonatanKra Sep 19, 2024
c743b05
Lint
Sep 19, 2024
feeecf4
Merge branch 'VIV-2065-dial-pad-events-leak' of https://github.com/Vo…
Sep 19, 2024
ff72bc8
Remove obsolete code
Sep 19, 2024
ebfc47e
fix(dial-pad): prevent focus loss after removal of delete button
Sep 19, 2024
6a84650
Linting
Sep 19, 2024
b7f711e
Merge remote-tracking branch 'origin/main' into VIV-2126-fix-delete-b…
Sep 24, 2024
35271aa
Merge remote-tracking branch 'origin/main' into VIV-2126-fix-delete-b…
Sep 24, 2024
41e7e22
Refactor last character blur handler
Sep 24, 2024
6f32548
Merge branch 'main' into VIV-2126-fix-delete-button-blur-effect
YonatanKra Oct 21, 2024
9404e96
Refactor
Oct 21, 2024
2716a69
Merge branch 'main' into VIV-2126-fix-delete-button-blur-effect
YonatanKra Oct 21, 2024
0a08a1c
Merge branch 'main' into VIV-2126-fix-delete-button-blur-effect
YonatanKra Oct 21, 2024
f250bd2
Refactor blur prevention
Oct 22, 2024
62d4ed6
Refactor
Oct 22, 2024
77c90f5
Merge branch 'main' into VIV-2126-fix-delete-button-blur-effect
YonatanKra Oct 22, 2024
99c37cf
Merge branch 'main' into VIV-2126-fix-delete-button-blur-effect
TaylorJ76 Oct 22, 2024
662a66f
Merge branch 'main' into VIV-2126-fix-delete-button-blur-effect
TaylorJ76 Oct 22, 2024
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
75 changes: 53 additions & 22 deletions libs/components/src/lib/dial-pad/dial-pad.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ describe('vwc-dial-pad', () => {

it('should set value in text field when has value attribute', async function () {
const value = '123';
element.value = value;
await elementUpdated(element);
await setValue(value);
expect(getTextField().value).toEqual(value);
});

Expand Down Expand Up @@ -145,30 +144,67 @@ describe('vwc-dial-pad', () => {
});
});

async function setValue(value: string) {
element.value = value;
await elementUpdated(element);
}

describe('delete', function () {
it('should show delete button when text field has value', async function () {
element.value = '123';
async function clickDeleteButton() {
getDeleteButton().click();
await elementUpdated(element);
}

it('should show delete button when text field has value', async function () {
await setValue('123');
expect(getDeleteButton()).not.toBeNull();
});

it('should remove last character from text field when clicked on delete button', async function () {
element.value = '123';
await elementUpdated(element);
getDeleteButton().click();
await elementUpdated(element);
await setValue('123');

await clickDeleteButton();

expect(getTextField().value).toEqual('12');
});

it('should emit a change event', async () => {
const spy = jest.fn();
element.addEventListener('change', spy);
element.value = '123';
await elementUpdated(element);
getDeleteButton().click();
await elementUpdated(element);
await setValue('123');

await clickDeleteButton();

expect(spy).toHaveBeenCalledTimes(1);
});

it('should emit an input event', async () => {
const spy = jest.fn();
element.addEventListener('input', spy);
await setValue('123');

await clickDeleteButton();

expect(spy).toHaveBeenCalledTimes(1);
});

it('should prevent blur event after deleting the last value', async () => {
const spy = jest.fn();
element.addEventListener('blur', spy);
await setValue('1');

await clickDeleteButton();

expect(spy).toHaveBeenCalledTimes(0);
});

it('should focus on the dialpad after deleting the last element', async () => {
await setValue('1');

await clickDeleteButton();

expect(document.activeElement === element).toBe(true);
});
});

describe('dial', function () {
Expand Down Expand Up @@ -237,8 +273,7 @@ describe('vwc-dial-pad', () => {
it('should fire dial event when enter is pressed on input', async function () {
const spy = jest.fn();
element.addEventListener('dial', spy);
element.value = '123';
await elementUpdated(element);
await setValue('123');
const input: HTMLInputElement = getTextField().querySelector(
'input'
) as HTMLInputElement;
Expand All @@ -255,17 +290,15 @@ describe('vwc-dial-pad', () => {
it('should fire dial event with value when clicked on call button', async function () {
const spy = jest.fn();
element.addEventListener('dial', spy);
element.value = '123';
await elementUpdated(element);
await setValue('123');
getCallButton().click();
expect(spy).toHaveBeenCalledTimes(1);
});

it('should prevent dial event when enter is pressed on delete button', async function () {
const spy = jest.fn();
element.value = '123';
await setValue('123');
element.addEventListener('dial', spy);
await elementUpdated(element);
getDeleteButton().dispatchEvent(
new KeyboardEvent('keydown', { key: 'Enter' })
);
Expand Down Expand Up @@ -440,8 +473,7 @@ describe('vwc-dial-pad', () => {

it('should set delete button disabled when has disabled attribute', async function () {
element.disabled = true;
element.value = '123';
await elementUpdated(element);
await setValue('123');
expect(getDeleteButton().disabled).toEqual(true);
});
});
Expand All @@ -463,8 +495,7 @@ describe('vwc-dial-pad', () => {

it('should set the delete button to be disabled', async function () {
element.callActive = true;
element.value = '123';
await elementUpdated(element);
await setValue('123');
expect(getDeleteButton().disabled).toBe(true);
});
});
Expand Down
22 changes: 16 additions & 6 deletions libs/components/src/lib/dial-pad/dial-pad.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ function stopPropagation(_: DialPad, { event: e }: ExecutionContext) {
e.stopImmediatePropagation();
}

function deleteLastCharacter(dialPad: DialPad) {
dialPad.value = dialPad.value.slice(0, -1);
dialPad.$emit('input');
dialPad.$emit('change');
if (dialPad.value === '') {
dialPad._textFieldEl.focus();
}
}

function renderTextField(textFieldTag: string, buttonTag: string) {
return html<DialPad>`<${textFieldTag} ${ref(
'_textFieldEl'
Expand All @@ -121,12 +130,13 @@ function renderTextField(textFieldTag: string, buttonTag: string) {
${when(
(x) => x.value && x.value.length && x.value.length > 0,
html`<${buttonTag}
slot="action-items" size='super-condensed' icon="backspace-line" aria-label="${(
x
) => x.deleteAriaLabel || x.locale.dialPad.deleteLabel}"
appearance='ghost' ?disabled="${(x) => x.disabled || x.callActive}" @click="${(
x
) => x._deleteLastCharacter()}">
slot="action-items"
size='super-condensed'
icon="backspace-line"
aria-label="${(x) => x.deleteAriaLabel || x.locale.dialPad.deleteLabel}"
appearance='ghost'
?disabled="${(x) => x.disabled || x.callActive}"
@click="${(x) => deleteLastCharacter(x)}">
</${buttonTag}>`
)}
</${textFieldTag}>`;
Expand Down
9 changes: 0 additions & 9 deletions libs/components/src/lib/dial-pad/dial-pad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,6 @@ export class DialPad extends FoundationElement {
_onDial = () => {
this.callActive ? this.$emit('end-call') : this.$emit('dial');
};

/**
*
* @internal
*/
_deleteLastCharacter = () => {
this.value = this.value.slice(0, -1);
this.$emit('change');
};
}

export interface DialPad extends Localized {}
Expand Down
Loading