diff --git a/src/aria/accordion/accordion.spec.ts b/src/aria/accordion/accordion.spec.ts index 2b5c31835341..38635ca4a004 100644 --- a/src/aria/accordion/accordion.spec.ts +++ b/src/aria/accordion/accordion.spec.ts @@ -363,17 +363,10 @@ describe('AccordionGroup', () => { }); it('should not allow keyboard navigation if group is disabled', () => { - configureAccordionComponent({disabledGroup: true, softDisabled: false}); - - downArrowKey(triggerElements[0]); - expect(isTriggerActive(triggerElements[1])).toBeFalse(); - }); - - it('should allow keyboard navigation if group is disabled', () => { configureAccordionComponent({disabledGroup: true}); downArrowKey(triggerElements[0]); - expect(isTriggerActive(triggerElements[1])).toBeTrue(); + expect(isTriggerActive(triggerElements[1])).toBeFalse(); }); it('should not allow expansion if group is disabled', () => { diff --git a/src/aria/listbox/listbox.spec.ts b/src/aria/listbox/listbox.spec.ts index 03553200c9b1..01b1c96db52e 100644 --- a/src/aria/listbox/listbox.spec.ts +++ b/src/aria/listbox/listbox.spec.ts @@ -195,14 +195,9 @@ describe('Listbox', () => { expect(listboxElement.getAttribute('tabindex')).toBe('-1'); }); - it('should set tabindex="0" for the listbox when disabled and focusMode is "roving when softDisabled is false"', () => { - setupListbox({disabled: true, focusMode: 'roving', softDisabled: false}); - expect(listboxElement.getAttribute('tabindex')).toBe('0'); - }); - - it('should set tabindex="-1" for the listbox when disabled and focusMode is "roving"', () => { + it('should set tabindex="0" for the listbox when disabled and focusMode is "roving"', () => { setupListbox({disabled: true, focusMode: 'roving'}); - expect(listboxElement.getAttribute('tabindex')).toBe('-1'); + expect(listboxElement.getAttribute('tabindex')).toBe('0'); }); it('should set initial focus (tabindex="0") on the first non-disabled option if no value is set', () => { @@ -645,7 +640,7 @@ describe('Listbox', () => { expect(isFocused(1)).toBe(true); }); - it('should not skip disabled options with ArrowDown when completely disabled', () => { + it('should not be focusable ArrowDown when completely disabled', () => { setupListbox({ focusMode, orientation: 'vertical', @@ -654,7 +649,7 @@ describe('Listbox', () => { }); down(); - expect(isFocused(0)).toBe(true); + expect(isFocused(0)).toBe(false); }); }); diff --git a/src/aria/private/behaviors/grid/grid-focus.ts b/src/aria/private/behaviors/grid/grid-focus.ts index 18def18c0b79..75ce16990322 100644 --- a/src/aria/private/behaviors/grid/grid-focus.ts +++ b/src/aria/private/behaviors/grid/grid-focus.ts @@ -143,7 +143,7 @@ export class GridFocus { /** Moves focus to the cell at the given coordinates if it's part of a focusable cell. */ focusCoordinates(coords: RowCol): boolean { - if (this.gridDisabled() && !this.inputs.softDisabled()) { + if (this.gridDisabled()) { return false; } diff --git a/src/aria/private/behaviors/grid/grid-navigation.spec.ts b/src/aria/private/behaviors/grid/grid-navigation.spec.ts index 25bf4ee64f02..669378f2b394 100644 --- a/src/aria/private/behaviors/grid/grid-navigation.spec.ts +++ b/src/aria/private/behaviors/grid/grid-navigation.spec.ts @@ -158,13 +158,13 @@ describe('GridNavigation', () => { expect(gridNav.peek(direction.Up, from, 'continuous')).toEqual({row: 3, col: 2}); }); - it('should return the next coordinates even if all cells are disabled', () => { + it('should return undefined if all cells are disabled', () => { cells.flat().forEach(cell => cell.disabled.set(true)); gridNav.gotoCoords({row: 1, col: 0}); const nextCoords = gridNav.peek(direction.Up, gridFocus.activeCoords()); - expect(nextCoords).toEqual({row: 0, col: 0}); + expect(nextCoords).toBeUndefined(); }); it('should return undefined if all cells are disabled when softDisabled is false', () => { @@ -210,23 +210,12 @@ describe('GridNavigation', () => { expect(gridNav.peek(direction.Down, from, 'continuous')).toEqual({row: 0, col: 2}); }); - it('should return the next coordinates even if all cells are disabled', () => { + it('should return undefined if completely disabled', () => { cells.flat().forEach(cell => cell.disabled.set(true)); gridNav.gotoCoords({row: 1, col: 0}); const nextCoords = gridNav.peek(direction.Down, gridFocus.activeCoords()); - expect(nextCoords).toEqual({row: 2, col: 0}); - }); - - it('should return undefined if all cells are disabled when softDisabled is false', () => { - const {gridNav} = setupGridNavigation(signal(cells), { - softDisabled: signal(false), - }); - cells.flat().forEach(cell => cell.disabled.set(true)); - - const nextCoords = gridNav.peek(direction.Down, {row: 1, col: 0}); - expect(nextCoords).toBeUndefined(); }); @@ -262,22 +251,11 @@ describe('GridNavigation', () => { expect(gridNav.peek(direction.Left, from, 'continuous')).toEqual({row: 3, col: 2}); }); - it('should return the next coordinates even if all cells are disabled', () => { - cells.flat().forEach(c => c.disabled.set(true)); - gridNav.gotoCoords({row: 1, col: 0}); - - const nextCoords = gridNav.peek(direction.Left, gridFocus.activeCoords()); - - expect(nextCoords).toEqual({row: 1, col: 2}); - }); - - it('should return undefined if all cells are disabled when softDisabled is false', () => { - const {gridNav} = setupGridNavigation(signal(cells), { - softDisabled: signal(false), - }); + it('should return undefined if completely disabled', () => { cells.flat().forEach(cell => cell.disabled.set(true)); + gridNav.gotoCoords({row: 1, col: 0}); - const nextCoords = gridNav.peek(direction.Left, {row: 1, col: 0}); + const nextCoords = gridNav.peek(direction.Down, gridFocus.activeCoords()); expect(nextCoords).toBeUndefined(); }); @@ -314,22 +292,11 @@ describe('GridNavigation', () => { expect(gridNav.peek(direction.Right, from, 'continuous')).toEqual({row: 1, col: 0}); }); - it('should return the next coordinates even if all cells are disabled', () => { - cells.flat().forEach(c => c.disabled.set(true)); - gridNav.gotoCoords({row: 1, col: 0}); - - const nextCoords = gridNav.peek(direction.Right, gridFocus.activeCoords()); - - expect(nextCoords).toEqual({row: 1, col: 1}); - }); - - it('should return undefined if all cells are disabled when softDisabled is false', () => { - const {gridNav} = setupGridNavigation(signal(cells), { - softDisabled: signal(false), - }); + it('should return undefined if completely disabled', () => { cells.flat().forEach(cell => cell.disabled.set(true)); + gridNav.gotoCoords({row: 1, col: 0}); - const nextCoords = gridNav.peek(direction.Right, {row: 1, col: 0}); + const nextCoords = gridNav.peek(direction.Down, gridFocus.activeCoords()); expect(nextCoords).toBeUndefined(); }); diff --git a/src/aria/private/behaviors/grid/grid-navigation.ts b/src/aria/private/behaviors/grid/grid-navigation.ts index 4efe0307f76a..48fa87910ca1 100644 --- a/src/aria/private/behaviors/grid/grid-navigation.ts +++ b/src/aria/private/behaviors/grid/grid-navigation.ts @@ -146,6 +146,8 @@ export class GridNavigation { wrap: 'continuous' | 'loop' | 'nowrap', allowDisabled: boolean = false, ): RowCol | undefined { + if (this.inputs.gridFocus.gridDisabled()) return undefined; + const fromCell = this.inputs.grid.getCell(fromCoords); const maxRowCount = this.inputs.grid.maxRowCount(); const maxColCount = this.inputs.grid.maxColCount(); diff --git a/src/aria/private/behaviors/grid/grid.spec.ts b/src/aria/private/behaviors/grid/grid.spec.ts index e5d81a3c2569..c3728cb6edf5 100644 --- a/src/aria/private/behaviors/grid/grid.spec.ts +++ b/src/aria/private/behaviors/grid/grid.spec.ts @@ -354,23 +354,13 @@ describe('Grid', () => { it('should return false if no focusable cell is found when state is empty', () => { const cells = createTestGrid(createGridA); cells.flat().forEach(c => c.disabled.set(true)); - const grid = setupGrid(signal(cells), {softDisabled: signal(false)}); + const grid = setupGrid(signal(cells)); const result = grid.resetState(); expect(result).toBe(false); expect(grid.focusBehavior.activeCell()).toBeUndefined(); }); - it('should return true and focus a cell if all cells are disabled but softDisabled is true', () => { - const cells = createTestGrid(createGridA); - cells.flat().forEach(c => c.disabled.set(true)); - const grid = setupGrid(signal(cells)); - - const result = grid.resetState(); - expect(result).toBe(true); - expect(grid.focusBehavior.activeCell()).toBe(cells[0][0]); - }); - it('should re-focus the active cell if it is stale but still exists', () => { const cellsSignal = signal(createTestGrid(createGridA)); const grid = setupGrid(cellsSignal); diff --git a/src/aria/private/behaviors/list-focus/list-focus.ts b/src/aria/private/behaviors/list-focus/list-focus.ts index 10813a6f4c59..ac0f43ce952b 100644 --- a/src/aria/private/behaviors/list-focus/list-focus.ts +++ b/src/aria/private/behaviors/list-focus/list-focus.ts @@ -66,14 +66,9 @@ export class ListFocus { return this.inputs.disabled() || this.inputs.items().every(i => i.disabled()); } - /** Whether the list is in a disabled state, but should still be focusable */ - isListDisabledFocusable(): boolean { - return this.isListDisabled() && !this.inputs.softDisabled(); - } - /** The id of the current active item. */ getActiveDescendant(): string | undefined { - if (this.isListDisabledFocusable()) { + if (this.isListDisabled()) { return undefined; } if (this.inputs.focusMode() === 'roving') { @@ -84,7 +79,7 @@ export class ListFocus { /** The tab index for the list. */ getListTabIndex(): -1 | 0 { - if (this.isListDisabledFocusable()) { + if (this.isListDisabled()) { return 0; } return this.inputs.focusMode() === 'activedescendant' ? 0 : -1; @@ -92,7 +87,7 @@ export class ListFocus { /** Returns the tab index for the given item. */ getItemTabIndex(item: T): -1 | 0 { - if (this.isListDisabledFocusable()) { + if (this.isListDisabled()) { return -1; } if (this.inputs.focusMode() === 'activedescendant') { @@ -103,7 +98,7 @@ export class ListFocus { /** Moves focus to the given item if it is focusable. */ focus(item: T, opts?: {focusElement?: boolean}): boolean { - if (this.isListDisabledFocusable() || !this.isFocusable(item)) { + if (this.isListDisabled() || !this.isFocusable(item)) { return false; } diff --git a/src/aria/private/behaviors/list/list.spec.ts b/src/aria/private/behaviors/list/list.spec.ts index e4421c2d10fb..3deab9c3e49b 100644 --- a/src/aria/private/behaviors/list/list.spec.ts +++ b/src/aria/private/behaviors/list/list.spec.ts @@ -160,9 +160,9 @@ describe('List Behavior', () => { it('should not change active index on navigation', () => { expect(list.inputs.activeItem()).toBe(list.inputs.items()[0]); list.next(); - expect(list.inputs.activeItem()).toBe(list.inputs.items()[1]); + expect(list.inputs.activeItem()).toBe(list.inputs.items()[0]); list.last(); - expect(list.inputs.activeItem()).toBe(list.inputs.items()[8]); + expect(list.inputs.activeItem()).toBe(list.inputs.items()[0]); }); it('should not select items', () => { @@ -170,8 +170,8 @@ describe('List Behavior', () => { expect(list.inputs.value()).toEqual([]); }); - it('should have a tabindex of 0', () => { - expect(list.tabIndex()).toBe(-1); + it('should have a tab index of 0', () => { + expect(list.tabIndex()).toBe(0); }); }); diff --git a/src/aria/private/behaviors/list/list.ts b/src/aria/private/behaviors/list/list.ts index 7418a717efc0..e22f218ede4b 100644 --- a/src/aria/private/behaviors/list/list.ts +++ b/src/aria/private/behaviors/list/list.ts @@ -226,7 +226,7 @@ export class List, V> { const moved = operation(); - if (moved && !this.disabled()) { + if (moved) { this.updateSelection(opts); } diff --git a/src/aria/tree/tree.spec.ts b/src/aria/tree/tree.spec.ts index 349a46fe9702..41ec89568f40 100644 --- a/src/aria/tree/tree.spec.ts +++ b/src/aria/tree/tree.spec.ts @@ -358,10 +358,10 @@ describe('Tree', () => { expect(treeElement.getAttribute('tabindex')).toBe('0'); }); - it('should set tabindex="0" for the tree when disabled', () => { + it('should set tabindex="0" for the tree when disabled when softDisabled is true', () => { updateTree({disabled: true, focusMode: 'roving'}); - expect(treeElement.getAttribute('tabindex')).toBe('-1'); + expect(treeElement.getAttribute('tabindex')).toBe('0'); }); it('should set initial focus (tabindex="0") on the first non-disabled item if no value is set', () => {