Skip to content

Feature request: export isInteractiveRole and isValidOwnedChild utilities derived from existing role data #601

@johanrd

Description

@johanrd

Several ESLint a11y plugins independently derive the same two queries from aria-query's role data:

1. "Is this role interactive?" — filter concrete roles whose superClass chain includes widget:

All five independently implement the same superClass.some(chain => chain.includes('widget')) loop. Three of them (angular-eslint, lit-a11y, eslint-plugin-ember) also independently arrived at the same two special cases: exclude progressbar (its value is always readonly), include toolbar (supports aria-activedescendant in practice).

2. "Is role X a valid owned child of role Y?" — walk requiredOwnedElements transitively, closing over superClass inheritance (e.g. treegrid inherits row from grid and treeitem from tree):

  • eslint-plugin-ember: same file as above (buildCompositeWidgetChildren)

The raw data is already in aria-query. The derivations are small but non-trivial (the transitive closure over superClass chains is the part each plugin gets slightly differently), and the special-case disagreements on progressbar/toolbar show the ecosystem hasn't converged.

Request

Would you consider exporting these as utilities from aria-query itself? Something like:

import { isInteractiveRole, isValidOwnedChild } from 'aria-query';

isInteractiveRole('button')              // true
isInteractiveRole('tooltip')             // false — document-structure role per §5.3.3
isValidOwnedChild('listbox', 'option')   // true
isValidOwnedChild('grid', 'gridcell')    // true — transitively via row
isValidOwnedChild('button', 'option')    // false

Cowritten by claude

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions