diff --git a/src/aria/combobox/combobox.spec.ts b/src/aria/combobox/combobox.spec.ts index 247cb8d1331d..5314c4a10cd6 100644 --- a/src/aria/combobox/combobox.spec.ts +++ b/src/aria/combobox/combobox.spec.ts @@ -33,7 +33,7 @@ describe('Combobox', () => { const click = (element: HTMLElement, eventInit?: PointerEventInit) => { focus(); - element.dispatchEvent(new PointerEvent('pointerup', {bubbles: true, ...eventInit})); + element.dispatchEvent(new PointerEvent('click', {bubbles: true, ...eventInit})); fixture.detectChanges(); }; @@ -584,7 +584,7 @@ describe('Combobox', () => { const click = (element: HTMLElement, eventInit?: PointerEventInit) => { focus(); - element.dispatchEvent(new PointerEvent('pointerup', {bubbles: true, ...eventInit})); + element.dispatchEvent(new PointerEvent('click', {bubbles: true, ...eventInit})); fixture.detectChanges(); }; diff --git a/src/aria/combobox/combobox.ts b/src/aria/combobox/combobox.ts index 9dc3aa33abe3..49ce65cabf96 100644 --- a/src/aria/combobox/combobox.ts +++ b/src/aria/combobox/combobox.ts @@ -74,7 +74,7 @@ import {toSignal} from '@angular/core/rxjs-interop'; '[attr.data-expanded]': 'expanded()', '(input)': '_pattern.onInput($event)', '(keydown)': '_pattern.onKeydown($event)', - '(pointerup)': '_pattern.onPointerup($event)', + '(click)': '_pattern.onClick($event)', '(focusin)': '_pattern.onFocusIn()', '(focusout)': '_pattern.onFocusOut($event)', }, diff --git a/src/aria/private/combobox/combobox.spec.ts b/src/aria/private/combobox/combobox.spec.ts index 5c8cb0f31cda..2922a50e61fc 100644 --- a/src/aria/private/combobox/combobox.spec.ts +++ b/src/aria/private/combobox/combobox.spec.ts @@ -352,7 +352,7 @@ describe('Combobox with Listbox Pattern', () => { it('should not expand when disabled', () => { const {combobox, inputEl} = getPatterns({disabled: true}); expect(combobox.expanded()).toBe(false); - combobox.onPointerup(clickInput(inputEl)); + combobox.onClick(clickInput(inputEl)); expect(combobox.expanded()).toBe(false); }); }); @@ -376,7 +376,7 @@ describe('Combobox with Listbox Pattern', () => { }); it('should select and commit on click', () => { - combobox.onPointerup(clickOption(listbox.inputs.items(), 0)); + combobox.onClick(clickOption(listbox.inputs.items(), 0)); expect(listbox.getSelectedItems()[0]).toBe(listbox.inputs.items()[0]); expect(listbox.inputs.values()).toEqual(['Apple']); expect(inputEl.value).toBe('Apple'); @@ -437,7 +437,7 @@ describe('Combobox with Listbox Pattern', () => { }); it('should select and commit on click', () => { - combobox.onPointerup(clickOption(listbox.inputs.items(), 3)); + combobox.onClick(clickOption(listbox.inputs.items(), 3)); expect(listbox.getSelectedItems()[0]).toBe(listbox.inputs.items()[3]); expect(listbox.inputs.values()).toEqual(['Blackberry']); expect(inputEl.value).toBe('Blackberry'); @@ -498,7 +498,7 @@ describe('Combobox with Listbox Pattern', () => { }); it('should select and commit on click', () => { - combobox.onPointerup(clickOption(listbox.inputs.items(), 3)); + combobox.onClick(clickOption(listbox.inputs.items(), 3)); expect(listbox.getSelectedItems()[0]).toBe(listbox.inputs.items()[3]); expect(listbox.inputs.values()).toEqual(['Blackberry']); expect(inputEl.value).toBe('Blackberry'); @@ -585,7 +585,7 @@ describe('Combobox with Listbox Pattern', () => { describe('with single-select', () => { it('should select and close on selection', () => { const {combobox, listbox, inputEl} = getPatterns({readonly: true}); - combobox.onPointerup(clickOption(listbox.inputs.items(), 2)); + combobox.onClick(clickOption(listbox.inputs.items(), 2)); expect(listbox.getSelectedItems()[0]).toBe(listbox.inputs.items()[2]); expect(listbox.inputs.values()).toEqual(['Banana']); expect(inputEl.value).toBe('Banana'); @@ -606,8 +606,8 @@ describe('Combobox with Listbox Pattern', () => { const {combobox, listbox, inputEl} = getPatterns({readonly: true}); (listbox.inputs.multi as WritableSignal).set(true); - combobox.onPointerup(clickOption(listbox.inputs.items(), 1)); - combobox.onPointerup(clickOption(listbox.inputs.items(), 2)); + combobox.onClick(clickOption(listbox.inputs.items(), 1)); + combobox.onClick(clickOption(listbox.inputs.items(), 2)); expect(listbox.inputs.values()).toEqual(['Apricot', 'Banana']); expect(inputEl.value).toBe('Apricot, Banana'); @@ -741,7 +741,7 @@ describe('Combobox with Tree Pattern', () => { }); it('should select and commit on click', () => { - combobox.onPointerup(clickTreeItem(tree.inputs.allItems(), 0)); + combobox.onClick(clickTreeItem(tree.inputs.allItems(), 0)); expect(tree.inputs.values()).toEqual(['Fruit']); expect(inputEl.value).toBe('Fruit'); }); @@ -755,7 +755,7 @@ describe('Combobox with Tree Pattern', () => { }); it('should select on focusout if the input text exactly matches an item', () => { - combobox.onPointerup(clickInput(inputEl)); + combobox.onClick(clickInput(inputEl)); type('Apple'); combobox.onFocusOut(new FocusEvent('focusout')); expect(tree.inputs.values()).toEqual(['Apple']); @@ -801,7 +801,7 @@ describe('Combobox with Tree Pattern', () => { }); it('should select and commit on click', () => { - combobox.onPointerup(clickTreeItem(tree.inputs.allItems(), 2)); + combobox.onClick(clickTreeItem(tree.inputs.allItems(), 2)); expect(tree.getSelectedItems()[0]).toBe(tree.inputs.allItems()[2]); expect(tree.inputs.values()).toEqual(['Banana']); expect(inputEl.value).toBe('Banana'); @@ -858,7 +858,7 @@ describe('Combobox with Tree Pattern', () => { }); it('should select and commit on click', () => { - combobox.onPointerup(clickTreeItem(tree.inputs.allItems(), 2)); + combobox.onClick(clickTreeItem(tree.inputs.allItems(), 2)); expect(tree.getSelectedItems()[0]).toBe(tree.inputs.allItems()[2]); expect(tree.inputs.values()).toEqual(['Banana']); expect(inputEl.value).toBe('Banana'); @@ -928,9 +928,9 @@ describe('Combobox with Tree Pattern', () => { describe('Readonly mode', () => { it('should select and close on selection', () => { const {combobox, tree, inputEl} = getPatterns({readonly: true}); - combobox.onPointerup(clickInput(inputEl)); + combobox.onClick(clickInput(inputEl)); expect(combobox.expanded()).toBe(true); - combobox.onPointerup(clickTreeItem(tree.inputs.allItems(), 0)); + combobox.onClick(clickTreeItem(tree.inputs.allItems(), 0)); expect(tree.inputs.values()).toEqual(['Fruit']); expect(inputEl.value).toBe('Fruit'); expect(combobox.expanded()).toBe(false); diff --git a/src/aria/private/combobox/combobox.ts b/src/aria/private/combobox/combobox.ts index 954beaba13d5..e9a53ad84bd5 100644 --- a/src/aria/private/combobox/combobox.ts +++ b/src/aria/private/combobox/combobox.ts @@ -282,8 +282,8 @@ export class ComboboxPattern, V> { return manager; }); - /** The pointerup event manager for the combobox. */ - pointerup = computed(() => + /** The click event manager for the combobox. */ + click = computed(() => new PointerEventManager().on(e => { if (e.target === this.inputs.inputEl()) { if (this.readonly()) { @@ -325,10 +325,10 @@ export class ComboboxPattern, V> { } } - /** Handles pointerup events for the combobox. */ - onPointerup(event: PointerEvent) { + /** Handles click events for the combobox. */ + onClick(event: MouseEvent) { if (!this.inputs.disabled()) { - this.pointerup().handle(event); + this.click().handle(event as PointerEvent); } } @@ -510,6 +510,12 @@ export class ComboboxPattern, V> { return; } + if (this.readonly()) { + this.expanded.set(false); + popupControls?.unfocus(); + return; + } + if (!opts?.reset) { if (this.inputs.filterMode() === 'manual') { if (