Skip to main content

vizia_core/modifiers/
accessibility.rs

1use super::internal;
2use crate::prelude::*;
3
4/// Modifiers for changing the accessibility properties of a view.
5pub trait AccessibilityModifiers: internal::Modifiable {
6    /// Sets the accessibility role of the view.
7    fn role(mut self, role: Role) -> Self {
8        let id = self.entity();
9
10        self.context().style.role.insert(id, role);
11
12        self.context().style.needs_access_update(id);
13
14        self
15    }
16
17    /// Sets the accessibility name of the view.
18    fn name<U: ToStringLocalized>(mut self, name: impl Res<U>) -> Self {
19        let entity = self.entity();
20        let current = self.current();
21        self.context().with_current(current, move |cx| {
22            name.set_or_bind(cx, move |cx, name| {
23                cx.style.name.insert(entity, name.get_value(cx).to_string_local(cx));
24                cx.style.needs_access_update(entity);
25            });
26        });
27
28        self
29    }
30
31    /// Sets the accessibility label relationship for the view using the ID of another view.
32    fn labeled_by(mut self, id: impl Into<String>) -> Self {
33        let entity = self.entity();
34        let id = id.into();
35
36        self.context().style.labelled_by.insert(entity, id);
37        self.context().style.needs_access_update(entity);
38
39        self
40    }
41
42    /// Sets the accessibility description relationship for the view using the ID of another view.
43    fn described_by(mut self, id: impl Into<String>) -> Self {
44        let entity = self.entity();
45        let id = id.into();
46
47        self.context().style.described_by.insert(entity, id);
48        self.context().style.needs_access_update(entity);
49
50        self
51    }
52
53    /// Sets the accessibility controls relationship for the view using the ID of another view.
54    fn controls(mut self, id: impl Into<String>) -> Self {
55        let entity = self.entity();
56        let id = id.into();
57
58        self.context().style.controls.insert(entity, id);
59        self.context().style.needs_access_update(entity);
60
61        self
62    }
63
64    /// Sets the accessibility active descendant relationship for the view.
65    fn active_descendant<U: Into<String> + Clone + 'static>(
66        mut self,
67        id: impl Res<U> + 'static,
68    ) -> Self {
69        let entity = self.entity();
70        let current = self.current();
71        self.context().with_current(current, |cx| {
72            id.set_or_bind(cx, move |cx, id| {
73                cx.style.active_descendant.insert(entity, id.get_value(cx).into());
74                cx.style.needs_access_update(entity);
75            });
76        });
77
78        self
79    }
80
81    // /// Sets the accessibility default action for the view.
82    // fn default_action_verb(mut self, action_verb: DefaultActionVerb) -> Self {
83    //     let id = self.entity();
84
85    //     self.context().style.default_action_verb.insert(id, action_verb);
86    //     self.context().style.needs_access_update(id);
87
88    //     self
89    // }
90
91    /// Sets whether the view should act as an accessibility live region.
92    fn live(mut self, live: Live) -> Self {
93        let id = self.entity();
94
95        self.context().style.live.insert(id, live);
96        self.context().style.needs_access_update(id);
97
98        self
99    }
100
101    /// Sets whether the view should be hidden from accessibility.
102    fn hidden<U: Into<bool>>(mut self, hidden: impl Res<U>) -> Self {
103        let entity = self.entity();
104        let current = self.current();
105        self.context().with_current(current, |cx| {
106            hidden.set_or_bind(cx, move |cx, hidden| {
107                cx.style.hidden.insert(entity, hidden.get_value(cx).into());
108                cx.style.needs_access_update(entity);
109            });
110        });
111
112        self
113    }
114
115    /// Sets whether the view should be announced as expanded (`true`) or collapsed (`false`).
116    fn expanded<U: Into<bool>>(mut self, expanded: impl Res<U>) -> Self {
117        let entity = self.entity();
118        let current = self.current();
119        self.context().with_current(current, |cx| {
120            expanded.set_or_bind(cx, move |cx, expanded| {
121                cx.style.expanded.insert(entity, expanded.get_value(cx).into());
122                cx.style.needs_access_update(entity);
123            });
124        });
125
126        self
127    }
128
129    /// Sets whether the view should be announced as selected (`true`) or not selected (`false`).
130    fn selected<U: Into<bool>>(mut self, selected: impl Res<U>) -> Self {
131        let entity = self.entity();
132        let current = self.current();
133        self.context().with_current(current, |cx| {
134            selected.set_or_bind(cx, move |cx, selected| {
135                cx.style.selected.insert(entity, selected.get_value(cx).into());
136                cx.style.needs_access_update(entity);
137            });
138        });
139
140        self
141    }
142
143    /// Sets the accessibility orientation of the view.
144    /// This does not affect the layout of the view, but is used to inform
145    /// assistive technologies of the orientation of the view.
146    fn orientation<U: Into<Orientation>>(mut self, orientation: impl Res<U>) -> Self {
147        let entity = self.entity();
148        let current = self.current();
149        self.context().with_current(current, |cx| {
150            orientation.set_or_bind(cx, move |cx, orientation| {
151                let orientation_value = orientation.get_value(cx).into();
152
153                if orientation_value == Orientation::Horizontal {
154                    cx.with_current(entity, |cx| {
155                        cx.toggle_class("horizontal", true);
156                        cx.toggle_class("vertical", false);
157                    });
158                } else {
159                    cx.with_current(entity, |cx| {
160                        cx.toggle_class("horizontal", false);
161                        cx.toggle_class("vertical", true);
162                    });
163                }
164                cx.style.orientation.insert(entity, orientation_value);
165                cx.style.needs_access_update(entity);
166            });
167        });
168
169        self
170    }
171
172    /// Sets the accessibility numeric value for the view.
173    fn numeric_value<U: Into<f64>>(mut self, value: impl Res<U>) -> Self {
174        let entity = self.entity();
175        let current = self.current();
176        self.context().with_current(current, |cx| {
177            value.set_or_bind(cx, move |cx, val| {
178                let v = val.get_value(cx).into();
179
180                cx.style.numeric_value.insert(entity, v);
181                cx.style.needs_access_update(entity);
182            });
183        });
184
185        self
186    }
187
188    /// Sets the accessibility text value for the view.
189    fn text_value<U: ToStringLocalized>(mut self, value: impl Res<U>) -> Self {
190        let entity = self.entity();
191        let current = self.current();
192        self.context().with_current(current, move |cx| {
193            value.set_or_bind(cx, move |cx, val| {
194                cx.style.text_value.insert(entity, val.get_value(cx).to_string_local(cx));
195                cx.style.needs_access_update(entity);
196            });
197        });
198
199        self
200    }
201}
202
203impl<V: View> AccessibilityModifiers for Handle<'_, V> {}