2
respostas

Acessibilidade para árvores de dados

Como faço para que o KeyboardManagedItem retorne a lista de items em todos os subníveis? Eu estou trabalhando na acessbilidade de um sidnav menu e segundo o WCAG isso deve seguir os critérios de uma treeview com navegação horizontal e lateral

2 respostas

Para que o KeyboardManagedItem retorne a lista de itens em todos os subníveis, você precisará implementar a lógica recursiva para percorrer a árvore de itens e criar a lista de itens.

Uma forma de fazer isso é definir uma função recursiva que percorre os itens do menu e, para cada item que possui subníveis, chama a mesma função para percorrer os subníveis e adicionar os itens à lista. Por exemplo:

interface MenuItem {
  label: string;
  subitems?: MenuItem[];
}

function getFlattenedMenuItems(items: MenuItem[]): MenuItem[] {
  let flattenedItems: MenuItem[] = [];
  for (let item of items) {
    flattenedItems.push(item);
    if (item.subitems) {
      flattenedItems = flattenedItems.concat(getFlattenedMenuItems(item.subitems));
    }
  }
  return flattenedItems;
}

Essa função getFlattenedMenuItems recebe uma lista de itens de menu e retorna uma lista com todos os itens, incluindo os subníveis.

Depois, você pode usar essa função para obter a lista completa de itens e passar para o KeyboardManagedItem:

<KeyboardManagedItem [items]="getFlattenedMenuItems(menuItems)">
  <!-- conteúdo do menu -->
</KeyboardManagedItem>

Assim, o KeyboardManagedItem irá gerenciar a navegação entre todos os itens do menu, incluindo os subníveis.

Muito obrigado pela resposta, Silvino. Após aprofundar na documentação eu consegui resolver com uma outra abordagem mais simples, apenas adicionando a opção { descendants: true} no @ContentChildren. Ficou assim:

export class KeyboardManagerDirective {
  @ContentChildren(KeyboardManagedItemDirective, {descendants: true})
  public itemsWithDescendants!: QueryList<KeyboardManagedItemDirective>;

  @HostListener('keyup', ['$event'])
  public manageKeys(event: KeyboardEvent): void {
    switch (event.key) {
      case 'Tab':
        this.moveFocus(Direction.CURRENT).focus();
        break;
      case 'ArrowUp':
        this.moveFocus(Direction.PREV).focus();
        break;
      case 'ArrowDown':
        this.moveFocus(Direction.NEXT).focus();
        break;
      case 'ArrowLeft':
        this.moveFocus(Direction.PREV).focus();
        break;
      case 'ArrowRight':
        this.moveFocus(Direction.NEXT).focus();
        break;
    }
  }