Skip to content

Commit

Permalink
Fix Bug in Accessible/Focusable Behavior (#9840)
Browse files Browse the repository at this point in the history
* Implement Focus Fix

* Fix Button

* Change files

* Remove Example Changes

* Fix Format

* Remove Unneeded

* Address Feedback

* Fix Prettier

* Fix Bug
  • Loading branch information
chiaramooney authored Apr 21, 2022
1 parent 73a4b1c commit 8c37ad2
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Implement Focus Fix",
"packageName": "react-native-windows",
"email": "34109996+chiaramooney@users.noreply.github.com",
"dependentChangeType": "patch"
}
32 changes: 32 additions & 0 deletions vnext/Microsoft.ReactNative/Views/ControlViewManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <JSValueWriter.h>
#include <Utils/PropertyUtils.h>

#include <UI.Xaml.Automation.Peers.h>

#ifdef USE_WINUI3
#define TAB_INDEX_PROPERTY xaml::UIElement::TabIndexProperty
#define TAB_STOP_PROPERTY xaml::UIElement::IsTabStopProperty
Expand Down Expand Up @@ -80,11 +82,18 @@ bool ControlViewManager::UpdateProperty(
}
} else if (propertyName == "focusable") {
if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean) {
IsFocusable(propertyValue.AsBoolean());
control.IsTabStop(propertyValue.AsBoolean());
} else if (propertyValue.IsNull()) {
control.ClearValue(TAB_STOP_PROPERTY());
IsFocusable(false);
}
} else {
if (propertyName == "accessible") {
if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean) {
IsAccessible(propertyValue.AsBoolean());
}
}
ret = Super::UpdateProperty(nodeToUpdate, propertyName, propertyValue);
}
}
Expand All @@ -96,6 +105,16 @@ bool ControlViewManager::UpdateProperty(
return ret;
}

void ControlViewManager::OnPropertiesUpdated(ShadowNodeBase *node) {
auto control(node->GetView().as<xaml::Controls::Control>());

if (IsAccessible() != IsFocusable()) {
control.IsTabStop(false);
xaml::Automation::AutomationProperties::SetAccessibilityView(
control, xaml::Automation::Peers::AccessibilityView::Raw);
}
}

void ControlViewManager::OnViewCreated(XamlView view) {
// Set the default cornerRadius to 0 for Control: WinUI usually default cornerRadius to 2
// Only works on >= RS5 because Control.CornerRadius is only supported >= RS5
Expand All @@ -104,4 +123,17 @@ void ControlViewManager::OnViewCreated(XamlView view) {
}
}

void ControlViewManager::IsAccessible(bool accessible) {
m_isAccessible = accessible;
}
bool ControlViewManager::IsAccessible() {
return m_isAccessible;
}
void ControlViewManager::IsFocusable(bool focusable) {
m_isFocusable = focusable;
}
bool ControlViewManager::IsFocusable() {
return m_isFocusable;
}

} // namespace Microsoft::ReactNative
11 changes: 11 additions & 0 deletions vnext/Microsoft.ReactNative/Views/ControlViewManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ class REACTWINDOWS_EXPORT ControlViewManager : public FrameworkElementViewManage

protected:
void OnViewCreated(XamlView view) override;

void OnPropertiesUpdated(ShadowNodeBase *node) override;

private:
void IsAccessible(bool accessible);
bool IsAccessible();
void IsFocusable(bool focusable);
bool IsFocusable();

bool m_isAccessible = true;
bool m_isFocusable = true;
};

} // namespace Microsoft::ReactNative
21 changes: 21 additions & 0 deletions vnext/Microsoft.ReactNative/Views/ViewViewManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "ViewControl.h"

#include <UI.Xaml.Automation.Peers.h>
#include "DynamicAutomationProperties.h"

#include <JSValueWriter.h>
Expand Down Expand Up @@ -127,6 +128,14 @@ class ViewShadowNode : public ShadowNodeBase {
GetControl().IsTabStop(m_isFocusable);
}

bool IsAccessible() const {
return m_isAccessible;
}

void IsAccessible(bool isAccessible) {
m_isAccessible = isAccessible;
}

bool IsHitTestBrushRequired() const {
return IsRegisteredForMouseEvents();
}
Expand Down Expand Up @@ -251,6 +260,7 @@ class ViewShadowNode : public ShadowNodeBase {
bool m_enableFocusRing = true;
bool m_onClick = false;
bool m_isFocusable = false;
bool m_isAccessible = false;
int32_t m_tabIndex = std::numeric_limits<std::int32_t>::max();

xaml::Controls::ContentControl::GotFocus_revoker m_contentControlGotFocusRevoker{};
Expand Down Expand Up @@ -420,6 +430,11 @@ bool ViewViewManager::UpdateProperty(
pViewShadowNode->TabIndex(std::numeric_limits<std::int32_t>::max());
}
} else {
if (propertyName == "accessible") {
if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean) {
pViewShadowNode->IsAccessible(propertyValue.AsBoolean());
}
}
ret = Super::UpdateProperty(nodeToUpdate, propertyName, propertyValue);
}
}
Expand Down Expand Up @@ -563,6 +578,12 @@ void ViewViewManager::TryUpdateView(

if (useControl)
pViewShadowNode->GetControl().Content(visualRoot);

if (useControl && pViewShadowNode->IsAccessible() != pViewShadowNode->IsFocusable()) {
pViewShadowNode->GetControl().IsTabStop(false);
xaml::Automation::AutomationProperties::SetAccessibilityView(
pViewShadowNode->GetControl(), xaml::Automation::Peers::AccessibilityView::Raw);
}
}

void ViewViewManager::SetLayoutProps(
Expand Down
1 change: 1 addition & 0 deletions vnext/src/Libraries/Components/Button.windows.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ class Button extends React.Component<
if (Platform.OS === 'windows') {
return (
<Touchable
accessible={accessible}
accessibilityLabel={accessibilityLabel}
accessibilityHint={accessibilityHint}
accessibilityLanguage={accessibilityLanguage}
Expand Down

0 comments on commit 8c37ad2

Please sign in to comment.