Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 1 addition & 8 deletions src/aria/accordion/accordion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
13 changes: 4 additions & 9 deletions src/aria/listbox/listbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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',
Expand All @@ -654,7 +649,7 @@ describe('Listbox', () => {
});

down();
expect(isFocused(0)).toBe(true);
expect(isFocused(0)).toBe(false);
});
});

Expand Down
2 changes: 1 addition & 1 deletion src/aria/private/behaviors/grid/grid-focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export class GridFocus<T extends GridFocusCell> {

/** 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;
}

Expand Down
51 changes: 9 additions & 42 deletions src/aria/private/behaviors/grid/grid-navigation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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();
});

Expand Down Expand Up @@ -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();
});
Expand Down Expand Up @@ -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();
});
Expand Down
2 changes: 2 additions & 0 deletions src/aria/private/behaviors/grid/grid-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ export class GridNavigation<T extends GridNavigationCell> {
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();
Expand Down
12 changes: 1 addition & 11 deletions src/aria/private/behaviors/grid/grid.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
13 changes: 4 additions & 9 deletions src/aria/private/behaviors/list-focus/list-focus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,9 @@ export class ListFocus<T extends ListFocusItem> {
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') {
Expand All @@ -84,15 +79,15 @@ export class ListFocus<T extends ListFocusItem> {

/** The tab index for the list. */
getListTabIndex(): -1 | 0 {
if (this.isListDisabledFocusable()) {
if (this.isListDisabled()) {
return 0;
}
return this.inputs.focusMode() === 'activedescendant' ? 0 : -1;
}

/** 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') {
Expand All @@ -103,7 +98,7 @@ export class ListFocus<T extends ListFocusItem> {

/** 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;
}

Expand Down
8 changes: 4 additions & 4 deletions src/aria/private/behaviors/list/list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,18 +160,18 @@ 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', () => {
list.next({selectOne: true});
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);
});
});

Expand Down
2 changes: 1 addition & 1 deletion src/aria/private/behaviors/list/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ export class List<T extends ListItem<V>, V> {

const moved = operation();

if (moved && !this.disabled()) {
if (moved) {
this.updateSelection(opts);
}

Expand Down
4 changes: 2 additions & 2 deletions src/aria/tree/tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
Loading