From 34d87cbd05a193d59101a789ff53ff99c2669643 Mon Sep 17 00:00:00 2001 From: Cheng-Hsuan Tsai Date: Fri, 17 Apr 2026 06:41:26 +0000 Subject: [PATCH] refactor(aria/grid): migrate Grid to use ClickEventManager --- goldens/aria/private/index.api.md | 4 ++-- src/aria/grid/grid.spec.ts | 6 +++--- src/aria/grid/grid.ts | 2 +- src/aria/private/grid/grid.spec.ts | 30 +++++++++++++++--------------- src/aria/private/grid/grid.ts | 14 +++++++------- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/goldens/aria/private/index.api.md b/goldens/aria/private/index.api.md index b6c1d72b8fa7..a83ab2936716 100644 --- a/goldens/aria/private/index.api.md +++ b/goldens/aria/private/index.api.md @@ -378,6 +378,7 @@ export class GridPattern { readonly activeDescendant: SignalLike; readonly anchorCell: SignalLike; readonly cells: SignalLike; + readonly clickManager: SignalLike>; readonly disabled: SignalLike; readonly dragging: WritableSignalLike; focusEffect(): void; @@ -389,12 +390,11 @@ export class GridPattern { readonly keydown: SignalLike>; readonly multiSelectable: SignalLike; readonly nextColKey: SignalLike<"ArrowRight" | "ArrowLeft">; + onClick(event: PointerEvent): void; onFocusIn(event: FocusEvent): void; onFocusOut(event: FocusEvent): void; onKeydown(event: KeyboardEvent): void; - onPointerdown(event: PointerEvent): void; readonly pauseNavigation: SignalLike; - readonly pointerdown: SignalLike>; readonly prevColKey: SignalLike<"ArrowRight" | "ArrowLeft">; resetFocusEffect(): void; resetStateEffect(): void; diff --git a/src/aria/grid/grid.spec.ts b/src/aria/grid/grid.spec.ts index c3d4c3c074f1..595aeec19bb8 100644 --- a/src/aria/grid/grid.spec.ts +++ b/src/aria/grid/grid.spec.ts @@ -59,7 +59,7 @@ describe('Grid directives', () => { }; const pointerDown = (target: HTMLElement, eventInit: PointerEventInit = {}) => { - target.dispatchEvent(new PointerEvent('pointerdown', {bubbles: true, ...eventInit})); + target.dispatchEvent(new PointerEvent('click', {bubbles: true, ...eventInit})); fixture.detectChanges(); }; @@ -468,7 +468,7 @@ describe('Grid directives', () => { }); }); - describe('pointer interactions', () => { + describe('click interactions', () => { beforeEach(() => { setupGrid({ enableSelection: true, @@ -479,7 +479,7 @@ describe('Grid directives', () => { fixture.detectChanges(); }); - it('should focus and select the clicked cell on pointerdown', () => { + it('should focus and select the clicked cell on click', () => { const cell = gridElement.querySelector('#c1-1') as HTMLElement; expect(cell.getAttribute('aria-selected')).toBe('false'); diff --git a/src/aria/grid/grid.ts b/src/aria/grid/grid.ts index bb6bb34ab44b..83e153c7b05c 100644 --- a/src/aria/grid/grid.ts +++ b/src/aria/grid/grid.ts @@ -54,7 +54,7 @@ import {GRID_ROW} from './grid-tokens'; '[attr.aria-multiselectable]': '_pattern.multiSelectable()', '[attr.aria-activedescendant]': '_pattern.activeDescendant()', '(keydown)': '_pattern.onKeydown($event)', - '(pointerdown)': '_pattern.onPointerdown($event)', + '(click)': '_pattern.onClick($event)', '(focusin)': '_pattern.onFocusIn($event)', '(focusout)': '_pattern.onFocusOut($event)', }, diff --git a/src/aria/private/grid/grid.spec.ts b/src/aria/private/grid/grid.spec.ts index 5cd9dbe0a404..ce7c42ecf3bd 100644 --- a/src/aria/private/grid/grid.spec.ts +++ b/src/aria/private/grid/grid.spec.ts @@ -515,7 +515,7 @@ describe('Grid', () => { }); }); - describe('Pointer Events', () => { + describe('Click Events', () => { let grid: GridPattern; beforeEach(() => { @@ -526,37 +526,37 @@ describe('Grid', () => { grid.setDefaultStateEffect(); }); - describe('Basic Pointer Actions', () => { - it('should move focus to the clicked cell on pointerdown', () => { + describe('Basic Click Actions', () => { + it('should move focus to the clicked cell on click', () => { const cells = grid.cells(); - grid.onPointerdown(createClickEvent(cells[0][1].element())); + grid.onClick(createClickEvent(cells[0][1].element())); expect(grid.gridBehavior.focusBehavior.activeCell()).toBe(cells[0][1]); }); }); - describe('Pointer Selection', () => { - it('should follow focus in follow mode on pointerdown', () => { + describe('Click Selection', () => { + it('should follow focus in follow mode on click', () => { (gridInputs.selectionMode as WritableSignalLike<'follow' | 'explicit'>).set('follow'); const cell = grid.cells()[0][1]; - grid.onPointerdown(createClickEvent(cell.element())); + grid.onClick(createClickEvent(cell.element())); expect(cell.selected()).toBe(true); }); - it('should toggle selection in explicit mode on pointerdown', () => { + it('should toggle selection in explicit mode on click', () => { (gridInputs.selectionMode as WritableSignalLike<'follow' | 'explicit'>).set('explicit'); const cell = grid.cells()[0][1]; - grid.onPointerdown(createClickEvent(cell.element())); + grid.onClick(createClickEvent(cell.element())); expect(cell.selected()).toBe(true); - grid.onPointerdown(createClickEvent(cell.element())); + grid.onClick(createClickEvent(cell.element())); expect(cell.selected()).toBe(false); }); - it('should support multi-selection with Ctrl+pointerdown', () => { + it('should support multi-selection with Ctrl+click', () => { (gridInputs.multi as WritableSignalLike).set(true); const cells = grid.cells(); - grid.onPointerdown(createClickEvent(cells[0][0].element())); - grid.onPointerdown(createClickEvent(cells[0][1].element(), {control: true})); + grid.onClick(createClickEvent(cells[0][0].element())); + grid.onClick(createClickEvent(cells[0][1].element(), {control: true})); expect(cells[0][0].selected()).toBe(true); expect(cells[0][1].selected()).toBe(true); }); @@ -664,12 +664,12 @@ describe('Grid', () => { expect(grid.gridBehavior.focusBehavior.activeCell()).toBeUndefined(); // Should stay undefined, meaning default state was skipped }); - it('should NOT set default state if pointer interacted', () => { + it('should NOT set default state if click interacted', () => { const gridInputs = getDefaultGridInputs(); const data = [{cells: [{}, {}]}, {cells: [{}, {}]}]; const {grid} = createGrid(data, gridInputs); const cells = grid.cells(); - grid.onPointerdown({target: cells[0][0].element()} as unknown as PointerEvent); // Interaction + grid.onClick({target: cells[0][0].element()} as unknown as PointerEvent); // Interaction cells[0][1].inputs.selected.set(true); grid.setDefaultStateEffect(); diff --git a/src/aria/private/grid/grid.ts b/src/aria/private/grid/grid.ts index 2f557b2e383c..ff02e5aebbae 100644 --- a/src/aria/private/grid/grid.ts +++ b/src/aria/private/grid/grid.ts @@ -7,7 +7,7 @@ */ import {SignalLike, computed, signal, untracked} from '../behaviors/signal-like/signal-like'; -import {KeyboardEventManager, PointerEventManager, Modifier} from '../behaviors/event-manager'; +import {KeyboardEventManager, ClickEventManager, Modifier} from '../behaviors/event-manager'; import {NavOptions, Grid, GridInputs as GridBehaviorInputs} from '../behaviors/grid'; import type {GridRowPattern} from './row'; import type {GridCellPattern} from './cell'; @@ -139,9 +139,9 @@ export class GridPattern { return manager; }); - /** The pointerdown event manager for the grid. */ - readonly pointerdown = computed(() => { - const manager = new PointerEventManager(); + /** The click event manager for the grid. */ + readonly clickManager = computed(() => { + const manager = new ClickEventManager(); // Navigation without selection. if (!this.inputs.enableSelection()) { @@ -205,12 +205,12 @@ export class GridPattern { this.keydown().handle(event); } - /** Handles pointerdown events on the grid. */ - onPointerdown(event: PointerEvent) { + /** Handles click events on the grid. */ + onClick(event: PointerEvent) { if (this.disabled()) return; this.hasBeenInteracted.set(true); - this.pointerdown().handle(event); + this.clickManager().handle(event); } /** Handles focusin events on the grid. */