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

Consider making UseFocus::attribute an opaque type. #886

Open
Tropix126 opened this issue Sep 14, 2024 · 0 comments
Open

Consider making UseFocus::attribute an opaque type. #886

Tropix126 opened this issue Sep 14, 2024 · 0 comments
Labels
internal impovement👍 Internal code improvements

Comments

@Tropix126
Copy link
Contributor

Tropix126 commented Sep 14, 2024

Currently the user can pass their own accesskit ID into a11y_id, which is intended for UseFocus at the moment due to having all types public:

use dioxus_core::AttributeValue;
use freya_node_state::CustomAttributeValues;

#[allow(non_snake_case)]
#[component]
pub fn BadComponent() -> Element {
    rsx!(
        rect {
            a11y_id: AttributeValue::any_value(
                CustomAttributeValues::AccessibilityId(accesskit::NodeId(0))
            ),
        }
    )
}

This is bad, because it allows the user to pass a duplicate accessibility ID which can mess up the tree in unexpected ways. Generally accesskit node IDs shouldn't be exposed to users at all, since they can't know the current value of the ID counter (thus allowing for overlap with any given u64). To fix this, we can make UseFocus::attribute return an opaque wrapper type over accesskit::NodeId with the NodeId itself not publicly exposed, making the only way to generate it being through a use_focus hook.

pub struct FocusAttribute(AccessibilityId); // AccessibilityId is not publicly exposed, so this struct can't be user-created

// ...

impl UseFocus {
    // ...

    /// Create a node focus ID attribute
    pub fn attribute(&self) -> AttributeValue {
        AttributeValue::any_value(CustomAttributeValues::Focus(
            FocusAttribute(self.id)
        ))
    }
}

This will enforce the invariant that accessibility IDs must first go through the AccessibilityGenerator counter.

pub fn Component() -> Element {
    let focus = use_focus();

    rsx!(
        rect {
            a11y_focus: focus.attribute(),
            // ...
        }
    )
}
@marc2332 marc2332 added the internal impovement👍 Internal code improvements label Sep 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
internal impovement👍 Internal code improvements
Projects
None yet
Development

No branches or pull requests

2 participants