Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design of bevy_a11y is BSN-unfriendly #17644

Open
viridia opened this issue Feb 2, 2025 · 1 comment
Open

Design of bevy_a11y is BSN-unfriendly #17644

viridia opened this issue Feb 2, 2025 · 1 comment
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

Comments

@viridia
Copy link
Contributor

viridia commented Feb 2, 2025

@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's AccessNode is a thin wrapper around AccessKit, and attempts to mimic its API, just as the Node component mimics the API structure of Taffy. There's been some discussion of refactoring the organization of Node (#10497), and there should be a similar discussion of re-organizing AccessNode.

Currently AccessNode has several aspects which make it problematic to use in a BSN-like context:

  • The properties are private, and only accessible through methods.
  • The methods use different calling conventions depending on the type of the property.
  • All of the accessibility properties are combined together in a single ECS component.

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 appropriate bevy_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

@viridia viridia added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Feb 2, 2025
@alice-i-cecile
Copy link
Member

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.

Fully agree. This is the right approach here, and we may need to eventually do something similar for taffy.

@alice-i-cecile alice-i-cecile added A-Accessibility A problem that prevents users with disabilities from using Bevy S-Needs-Design This issue requires design work to think about how it would best be accomplished A-UI Graphical user interfaces, styles, layouts, and widgets and removed S-Needs-Triage This issue needs to be labelled labels Feb 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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
Projects
None yet
Development

No branches or pull requests

2 participants