-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Core radio button and radio group #19778
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a mechanism that enforces exclusivity, atm more than radio button can be selected at a time.
It's also possible to construct nested radio buttons. That doesn't seem useful, probably they should be ignored after emitting a warning.
.iter_descendants(ev.target()) | ||
.filter_map(|child_id| match q_radio.get(child_id) { | ||
Ok((checked, false)) => Some((child_id, checked)), | ||
Ok((_, true)) | Err(_) => None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok((_, true)) | Err(_) => None, | |
_ => None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kind of like the fact that we're explicitly telling the person reading the code that there's both an error case and a disabled case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. I'm just easily distracted, so I'm always obsessed with removing any noise.
/// See <https://www.w3.org/WAI/ARIA/apg/patterns/radio>/ | ||
#[derive(Component, Debug)] | ||
#[require(AccessibilityNode(accesskit::Node::new(Role::RadioButton)), Checked)] | ||
pub struct CoreRadio; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub struct CoreRadio; | |
pub struct CoreRadio(Option<Entity>); |
Maybe to enforce exclusivity instead of using the Checked
component, you could propagate down the entity id of the currently selected radio button and store it in each CoreRadio
component. Then to check if a radio button is selected you'd compare its own entity id against the id stored in its CoreRadio
component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That could still result in multiple radio selections within a group if a currently selected radio button is reparented into another group or something though, I suppose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a lengthy doc comment concerning mutual exclusion.
I didn't want to mention reactivity in the comment, but in a reactive framework mutual exclusion is very simple. Each button's Checked
state is driven by a reactive formula of the form (radio_button_value == group_value). When the group value changes, the checked states change in response (regardless of whether the change was the result of clicking a button, or because the data changed programmatically for some other reason).
However, since we don't have reactivity (yet), I had to handwave over the issue by saying that the checked states are either updated by the app or some unspecified data-binding scheme.
It's hard to do more than this without resorting to Any
types to store the radio button values. (Either that or generic components, but I'd prefer not to go there).
In any case, as long as the app follows this pattern (checked driven by equality comparison) and each radio button has a unique value, then having more than one radio button selected at a time should never happen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I understand it's difficult without reactivity. It's just that mutual exclusivity is the defining characteristic of radio buttons, so expecting users to have to manage and enforce it themselves feels like it defeats the purpose of having this widget.
Maybe it's just not possible or at least not worth the effort at the moment though and this is the best we can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I share this sentiment. I'm not pleased with the fact that this logic is kinda punted up a layer, but I'm alright with moving forward for now in the absence of a clear alternate proposal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Straightforward enough :) Happy to continue to push this forward.
This was a mistake in my original PR #19778: a holdover from when Checked was not a marker component.
# Objective Core Radio Button and Radio Group widgets. Part of bevyengine#19236
Objective
Core Radio Button and Radio Group widgets. Part of #19236