Tooltips added on hover for AX sidebar

Summary: Adds on hover descriptions for some of the more esoteric properties in the accessibility sidebar panel such as accessibility-focused and all the talkback derived properties. Also change talkback-focusable and talkback-ignored to both be talkback-focusable.

Differential Revision: D9381676

fbshipit-source-id: 55ce854da24241a7c89b0c122c4c3ebd77438dbb
This commit is contained in:
Sara Valderrama
2018-08-20 09:31:39 -07:00
committed by Facebook Github Bot
parent 02cf3a90a2
commit c428de3948
5 changed files with 46 additions and 4 deletions

View File

@@ -686,7 +686,7 @@ public final class AccessibilityUtil {
public static void addTalkbackProperties(SonarObject.Builder props, View view) { public static void addTalkbackProperties(SonarObject.Builder props, View view) {
if (!AccessibilityEvaluationUtil.isTalkbackFocusable(view)) { if (!AccessibilityEvaluationUtil.isTalkbackFocusable(view)) {
props props
.put("talkback-ignored", true) .put("talkback-focusable", false)
.put("talkback-ignored-reasons", getTalkbackIgnoredReasons(view)); .put("talkback-ignored-reasons", getTalkbackIgnoredReasons(view));
} else { } else {
props props
@@ -729,7 +729,7 @@ public final class AccessibilityUtil {
if (!AccessibilityEvaluationUtil.isTalkbackFocusable(view)) { if (!AccessibilityEvaluationUtil.isTalkbackFocusable(view)) {
String reason = getTalkbackIgnoredReasons(view); String reason = getTalkbackIgnoredReasons(view);
return new SonarObject.Builder() return new SonarObject.Builder()
.put("talkback-ignored", true) .put("talkback-focusable", false)
.put("talkback-ignored-reasons", reason == null ? "" : reason) .put("talkback-ignored-reasons", reason == null ? "" : reason)
.build(); .build();
} else { } else {

View File

@@ -935,6 +935,27 @@ export default class Layout extends SonarPlugin<InspectorState> {
}); });
}; };
// returns object with all sidebar elements that should show more information
// on hover (needs to be kept up-to-date if names of properties change)
getAccessibilityTooltips() {
return {
'accessibility-focused':
'True if this element has the focus of an accessibility service',
'content-description':
'Text to label the content/functionality of this element ',
'important-for-accessibility':
'Marks this element as important to accessibility services, one of AUTO, YES, NO, NO_HIDE_DESCENDANTS',
'talkback-focusable': 'True if Talkback can focus on this element',
'talkback-focusable-reasons': 'Why Talkback can focus on this element',
'talkback-ignored': 'True if Talkback cannot focus on this element',
'talkback-ignored-reasons': 'Why Talkback cannot focus on the element',
'talkback-output':
'What Talkback will say when this element is focused (derived from role, content-description, and state of the element)',
'talkback-hint':
'What Talkback will say after output if hints are enabled',
};
}
renderSidebar = () => { renderSidebar = () => {
if (this.state.inAXMode) { if (this.state.inAXMode) {
// empty if no element selected w/in AX node tree // empty if no element selected w/in AX node tree
@@ -942,6 +963,7 @@ export default class Layout extends SonarPlugin<InspectorState> {
this.state.AXselected && ( this.state.AXselected && (
<InspectorSidebar <InspectorSidebar
element={this.state.AXelements[this.state.AXselected]} element={this.state.AXelements[this.state.AXselected]}
tooltips={this.getAccessibilityTooltips()}
onValueChanged={this.onDataValueChanged} onValueChanged={this.onDataValueChanged}
client={this.client} client={this.client}
/> />
@@ -1001,7 +1023,7 @@ export default class Layout extends SonarPlugin<InspectorState> {
onClick={this.onToggleAccessibility} onClick={this.onToggleAccessibility}
role="button" role="button"
tabIndex={-1} tabIndex={-1}
title="Toggle accessibility mode within the LayoutInspector"> title="Toggle to see the accessibility hierarchy">
<Glyph <Glyph
name="accessibility" name="accessibility"
size={16} size={16}

View File

@@ -133,6 +133,10 @@ type DataInspectorProps = {
* Ancestry of parent objects, used to avoid recursive objects. * Ancestry of parent objects, used to avoid recursive objects.
*/ */
ancestry: Array<Object>, ancestry: Array<Object>,
/**
* Object of properties that will have tooltips
*/
tooltips?: Object,
}; };
const defaultValueExtractor: DataValueExtractor = (value: any) => { const defaultValueExtractor: DataValueExtractor = (value: any) => {
@@ -408,6 +412,7 @@ export default class DataInspector extends Component<DataInspectorProps> {
path, path,
ancestry, ancestry,
collapsed, collapsed,
tooltips,
} = this.props; } = this.props;
// the data inspector makes values read only when setValue isn't set so we just need to set it // the data inspector makes values read only when setValue isn't set so we just need to set it
@@ -493,6 +498,7 @@ export default class DataInspector extends Component<DataInspectorProps> {
name={key} name={key}
data={metadata.data} data={metadata.data}
diff={metadata.diff} diff={metadata.diff}
tooltips={tooltips}
/> />
); );
@@ -523,7 +529,11 @@ export default class DataInspector extends Component<DataInspectorProps> {
// create name components // create name components
const nameElems = []; const nameElems = [];
if (typeof name !== 'undefined') { if (typeof name !== 'undefined') {
nameElems.push(<InspectorName key="name">{name}</InspectorName>); nameElems.push(
<InspectorName key="name" title={(tooltips && tooltips[name]) || ''}>
{name}
</InspectorName>,
);
nameElems.push(<span key="sep">: </span>); nameElems.push(<span key="sep">: </span>);
} }
@@ -549,6 +559,7 @@ export default class DataInspector extends Component<DataInspectorProps> {
/> />
); );
} }
descriptionOrPreview = ( descriptionOrPreview = (
<span> <span>
{nameElems} {nameElems}

View File

@@ -39,6 +39,10 @@ type ManagedDataInspectorProps = {|
* Whether all objects and arrays should be collapsed by default. * Whether all objects and arrays should be collapsed by default.
*/ */
collapsed?: boolean, collapsed?: boolean,
/**
* Object of all properties that will have tooltips
*/
tooltips?: Object,
|}; |};
type ManagedDataInspectorState = {| type ManagedDataInspectorState = {|
@@ -99,6 +103,7 @@ export default class ManagedDataInspector extends PureComponent<
onExpanded={this.onExpanded} onExpanded={this.onExpanded}
expandRoot={this.props.expandRoot} expandRoot={this.props.expandRoot}
collapsed={this.props.collapsed} collapsed={this.props.collapsed}
tooltips={this.props.tooltips}
/> />
); );
} }

View File

@@ -22,6 +22,7 @@ type InspectorSidebarSectionProps = {
data: any, data: any,
id: string, id: string,
onValueChanged: ?OnValueChanged, onValueChanged: ?OnValueChanged,
tooltips?: Object,
}; };
class InspectorSidebarSection extends Component<InspectorSidebarSectionProps> { class InspectorSidebarSection extends Component<InspectorSidebarSectionProps> {
@@ -65,6 +66,7 @@ class InspectorSidebarSection extends Component<InspectorSidebarSectionProps> {
extractValue={this.extractValue} extractValue={this.extractValue}
expandRoot={true} expandRoot={true}
collapsed={true} collapsed={true}
tooltips={this.props.tooltips}
/> />
</Panel> </Panel>
); );
@@ -73,6 +75,7 @@ class InspectorSidebarSection extends Component<InspectorSidebarSectionProps> {
type Props = {| type Props = {|
element: ?Element, element: ?Element,
tooltips?: Object,
onValueChanged: ?OnValueChanged, onValueChanged: ?OnValueChanged,
client: PluginClient, client: PluginClient,
|}; |};
@@ -117,6 +120,7 @@ export class InspectorSidebar extends Component<Props, State> {
for (const key in element.data) { for (const key in element.data) {
sections.push( sections.push(
<InspectorSidebarSection <InspectorSidebarSection
tooltips={this.props.tooltips}
key={key} key={key}
id={key} id={key}
data={element.data[key]} data={element.data[key]}