Design of bevy_a11y is BSN-unfriendly #17644
Labels
A-Accessibility
A problem that prevents users with disabilities from using Bevy
A-UI
Graphical user interfaces, styles, layouts, and widgets
C-Bug
An unexpected or incorrect behavior
S-Needs-Design
This issue requires design work to think about how it would best be accomplished
@cart has stated that his vision for BSN involves a particular design philosophy for entities and components, specifically one in which components are made up of ordinary properties which can be merged and patched. Unfortunately, the current design for
bevy_a11y
is rather incompatible with this vision. I believe the reason for this is that Bevy'sAccessNode
is a thin wrapper around AccessKit, and attempts to mimic its API, just as theNode
component mimics the API structure of Taffy. There's been some discussion of refactoring the organization ofNode
(#10497), and there should be a similar discussion of re-organizingAccessNode
.Currently
AccessNode
has several aspects which make it problematic to use in a BSN-like context:Consider for example, the property that controls whether an entity is "disabled" (grayed out). This is set currently via the no-argument method
.set_disabled()
and reset by the no-argument method.clear_disabled()
. A BSN template that wants to disable a widget can't simply merge in a disabled marker component, but instead must use a hook or bundle effect which calls the appropriatebevy_a11y
method.I anticipate that BSN templates are going to provide a layered approach where various patches control different aspects of a widget. For example, you might have a widget template that adds custom styling to a standard checkbox or button, using the patch mechanism. This customization process might involve accessibility properties: for example, the only difference between a checkbox and a toggle switch, from an accessibility perspective, is whether you use the "checkbox" role or the "switch" role, so the rest of the accessibility properties can be shared between the two widget types.
Because of this, I can well imagine wanting to merge together multiple BSN templates, each of which has opinions about various accessibility attributes: the template that determines the label or the role might not be the same template as the one which determines the checked or disable states. This is easy to do if these attributes are separate components, or (at least) allow overwriting of properties using patch. If setting properties requires calling of bespoke methods, however, the process becomes much more involved, as now any setting of a property becomes a read-modify-write operation.
Things get even tricker when we add interaction into the mix. Templates don't merely insert components; they also set up processes that keep those components up to date, either via a reactivity mechanism or via ECS systems that look for specific interaction components. Presumably a template that adds component X also wants to incorporate logic that keeps component X up to date. However, you have to be careful if multiple templates want to overwrite properties within same component. This argues against large, swiss-army-knife components that encompass too many concerns.
Obviously we aren't going to re-write our own version of AccessKit. Instead, I think the solution is to come up with our own idiomatic API, and then provide a transformation from that API into the AccessKit structure.
@alice-i-cecile
The text was updated successfully, but these errors were encountered: