Skip to content

Commit

Permalink
fix(checkbox): checked and indeterminate not updated during input…
Browse files Browse the repository at this point in the history
… event

Fixes #5028

The input event is dispatched before the change event, so we need to update state there instead of on change.

PiperOrigin-RevId: 588497817
  • Loading branch information
asyncLiz authored and copybara-github committed Dec 6, 2023
1 parent a6d984a commit e78a52f
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
7 changes: 6 additions & 1 deletion checkbox/internal/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export class Checkbox extends checkboxBaseClass {
?required=${this.required}
.indeterminate=${this.indeterminate}
.checked=${this.checked}
@input=${this.handleInput}
@change=${this.handleChange} />
<div class="outline"></div>
Expand All @@ -167,11 +168,15 @@ export class Checkbox extends checkboxBaseClass {
`;
}

private handleChange(event: Event) {
private handleInput(event: Event) {
const target = event.target as HTMLInputElement;
this.checked = target.checked;
this.indeterminate = target.indeterminate;
// <input> 'input' event bubbles and is composed, don't re-dispatch it.
}

private handleChange(event: Event) {
// <input> 'change' event is not composed, re-dispatch it.
redispatchEvent(this, event);
}

Expand Down
36 changes: 36 additions & 0 deletions checkbox/internal/checkbox_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,42 @@ describe('checkbox', () => {
expect(inputHandler).toHaveBeenCalledTimes(1);
expect(inputHandler).toHaveBeenCalledWith(jasmine.any(Event));
});

it('checkbox state is updated during input event listeners', async () => {
const {harness} = await setupTest();
let state = false;
const inputHandler = jasmine
.createSpy('inputHandler')
.and.callFake(() => {
state = harness.element.checked;
});

harness.element.addEventListener('input', inputHandler);

await harness.clickWithMouse();
expect(inputHandler).withContext('input listener').toHaveBeenCalled();
expect(state)
.withContext('checkbox.checked during input listener')
.toBeTrue();
});

it('checkbox state is updated during change event listeners', async () => {
const {harness} = await setupTest();
let state = false;
const changeHandler = jasmine
.createSpy('changeHandler')
.and.callFake(() => {
state = harness.element.checked;
});

harness.element.addEventListener('change', changeHandler);

await harness.clickWithMouse();
expect(changeHandler).withContext('change listener').toHaveBeenCalled();
expect(state)
.withContext('checkbox.checked during change listener')
.toBeTrue();
});
});

describe('checked', () => {
Expand Down

0 comments on commit e78a52f

Please sign in to comment.