Fabric: Support of accessibility events for <View> component

Summary: This also illustrates how we should use EventHandlers objects.

Reviewed By: fkgozali

Differential Revision: D8053357

fbshipit-source-id: cba084c8a871e40c7536720fce290c3467d33061
This commit is contained in:
Valentin Shergin 2018-05-22 15:48:24 -07:00 committed by Facebook Github Bot
parent 1064dad9bf
commit 20645681d1
8 changed files with 111 additions and 15 deletions

View File

@ -9,8 +9,10 @@
#import <React/RCTComponentViewProtocol.h>
#import <React/UIView+ComponentViewProtocol.h>
#import <fabric/core/EventHandlers.h>
#import <fabric/core/LayoutMetrics.h>
#import <fabric/core/Props.h>
#import <fabric/view/ViewEventHandlers.h>
NS_ASSUME_NONNULL_BEGIN
@ -21,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
@protected
facebook::react::LayoutMetrics _layoutMetrics;
facebook::react::SharedProps _props;
facebook::react::SharedViewEventHandlers _eventHandlers;
}
@end

View File

@ -8,13 +8,15 @@
#import "RCTViewComponentView.h"
#import <fabric/view/ViewProps.h>
#import <fabric/view/ViewEventHandlers.h>
using namespace facebook::react;
@implementation RCTViewComponentView
- (void)updateProps:(facebook::react::SharedProps)props
oldProps:(facebook::react::SharedProps)oldProps
- (void)updateProps:(SharedProps)props
oldProps:(SharedProps)oldProps
{
if (!oldProps) {
oldProps = _props ?: std::make_shared<ViewProps>();
@ -31,6 +33,12 @@ using namespace facebook::react;
// TODO: Implement all sutable non-layout <View> props.
}
- (void)updateEventHandlers:(SharedEventHandlers)eventHandlers
{
assert(std::dynamic_pointer_cast<const ViewEventHandlers>(eventHandlers));
_eventHandlers = std::static_pointer_cast<const ViewEventHandlers>(eventHandlers);
}
- (void)updateLayoutMetrics:(LayoutMetrics)layoutMetrics
oldLayoutMetrics:(LayoutMetrics)oldLayoutMetrics
{
@ -39,4 +47,24 @@ using namespace facebook::react;
_layoutMetrics = layoutMetrics;
}
#pragma mark - Accessibility Events
- (BOOL)accessibilityActivate
{
_eventHandlers->onAccessibilityTap();
return YES;
}
- (BOOL)accessibilityPerformMagicTap
{
_eventHandlers->onAccessibilityMagicTap();
return YES;
}
- (BOOL)didActivateAccessibilityCustomAction:(UIAccessibilityCustomAction *)action
{
_eventHandlers->onAccessibilityAction([action.name cStringUsingEncoding:NSASCIIStringEncoding]);
return YES;
}
@end

View File

@ -17,11 +17,13 @@ namespace react {
/*
* Descriptor for <Paragraph> component.
*/
class ParagraphComponentDescriptor: public ConcreteComponentDescriptor<ParagraphShadowNode> {
class ParagraphComponentDescriptor final:
public ConcreteComponentDescriptor<ParagraphShadowNode> {
public:
ParagraphComponentDescriptor():
ConcreteComponentDescriptor<ParagraphShadowNode>() {
ParagraphComponentDescriptor(SharedEventDispatcher eventDispatcher):
ConcreteComponentDescriptor<ParagraphShadowNode>(eventDispatcher) {
// Every single `ParagraphShadowNode` will have a reference to
// a shared `TextLayoutManager`.
textLayoutManager_ = std::make_shared<TextLayoutManager>();

View File

@ -12,6 +12,7 @@
#include <fabric/core/ShadowNode.h>
#include <fabric/debug/DebugStringConvertibleItem.h>
#include <fabric/view/AccessibleShadowNode.h>
#include <fabric/view/ViewEventHandlers.h>
#include <fabric/view/ViewProps.h>
#include <fabric/view/YogaLayoutableShadowNode.h>
@ -23,9 +24,9 @@ namespace react {
* as <View> and similar basic behaviour).
* For example: <Paragraph>, <Image>, but not <Text>, <RawText>.
*/
template <typename ViewPropsT>
template <typename ViewPropsT = ViewProps, typename ViewEventHandlersT = ViewEventHandlers>
class ConcreteViewShadowNode:
public ConcreteShadowNode<ViewPropsT>,
public ConcreteShadowNode<ViewPropsT, ViewEventHandlersT>,
public AccessibleShadowNode,
public YogaLayoutableShadowNode {
@ -37,21 +38,23 @@ public:
using ConcreteViewProps = ViewPropsT;
using SharedConcreteViewProps = std::shared_ptr<const ViewPropsT>;
using ConcreteViewEventHandlers = ViewEventHandlersT;
using SharedConcreteViewEventHandlers = std::shared_ptr<const ViewEventHandlersT>;
using SharedConcreteViewShadowNode = std::shared_ptr<const ConcreteViewShadowNode>;
ConcreteViewShadowNode(
const Tag &tag,
const Tag &rootTag,
const InstanceHandle &instanceHandle,
const SharedConcreteViewProps &props,
const SharedConcreteViewEventHandlers &eventHandlers,
const SharedShadowNodeSharedList &children,
const ShadowNodeCloneFunction &cloneFunction
):
ConcreteShadowNode<ViewPropsT>(
ConcreteShadowNode<ViewPropsT, ViewEventHandlersT>(
tag,
rootTag,
instanceHandle,
props,
eventHandlers,
children,
cloneFunction
),
@ -66,11 +69,13 @@ public:
ConcreteViewShadowNode(
const SharedConcreteViewShadowNode &shadowNode,
const SharedConcreteViewProps &props,
const SharedConcreteViewEventHandlers &eventHandlers,
const SharedShadowNodeSharedList &children
):
ConcreteShadowNode<ViewPropsT>(
ConcreteShadowNode<ViewPropsT, ViewEventHandlersT>(
shadowNode,
props,
eventHandlers,
children
),
AccessibleShadowNode(

View File

@ -0,0 +1,28 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "ViewEventHandlers.h"
namespace facebook {
namespace react {
#pragma mark - Accessibility
void ViewEventHandlers::onAccessibilityAction(const std::string &name) const {
dispatchEvent("accessibilityAction", folly::dynamic::object("action", name));
}
void ViewEventHandlers::onAccessibilityTap() const {
dispatchEvent("accessibilityTap");
}
void ViewEventHandlers::onAccessibilityMagicTap() const {
dispatchEvent("magicTap");
}
} // namespace react
} // namespace facebook

View File

@ -0,0 +1,33 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <memory>
#include <fabric/core/EventHandlers.h>
namespace facebook {
namespace react {
class ViewEventHandlers;
using SharedViewEventHandlers = std::shared_ptr<const ViewEventHandlers>;
class ViewEventHandlers:
public EventHandlers {
public:
using EventHandlers::EventHandlers;
void onAccessibilityAction(const std::string &name) const;
void onAccessibilityTap() const;
void onAccessibilityMagicTap() const;
};
} // namespace react
} // namespace facebook

View File

@ -20,7 +20,7 @@ class ViewShadowNode;
using SharedViewShadowNode = std::shared_ptr<const ViewShadowNode>;
class ViewShadowNode final:
public ConcreteViewShadowNode<ViewProps> {
public ConcreteViewShadowNode<ViewProps, ViewEventHandlers> {
public:

View File

@ -35,9 +35,6 @@ public:
const AccessibilityTraits accessibilityTraits {AccessibilityTraits::None};
const bool accessibilityViewIsModal {false};
const bool accessibilityElementsHidden {false};
const SharedDirectEventHandler onAccessibilityAction {nullptr};
const SharedDirectEventHandler onAccessibilityTap {nullptr};
const SharedDirectEventHandler onMagicTap {nullptr};
};
} // namespace react