diff --git a/Libraries/Components/View/ViewAccessibility.js b/Libraries/Components/View/ViewAccessibility.js index 1cd11667db1286..c0a475f721d60f 100644 --- a/Libraries/Components/View/ViewAccessibility.js +++ b/Libraries/Components/View/ViewAccessibility.js @@ -158,10 +158,6 @@ export type AccessibilityState = { ... }; -export type AccessibilityUnit = { - hours?: number, -}; - export type AccessibilityValue = $ReadOnly<{| /** * The minimum value of this component's range. (should be an integer) diff --git a/Libraries/Components/View/ViewPropTypes.js b/Libraries/Components/View/ViewPropTypes.js index a27db9facc45dd..bec5e2aa998adb 100644 --- a/Libraries/Components/View/ViewPropTypes.js +++ b/Libraries/Components/View/ViewPropTypes.js @@ -502,7 +502,7 @@ export type ViewProps = $ReadOnly<{| * Indicates to accessibility services that UI Component is in a specific State. */ accessibilityState?: ?AccessibilityState, - accessibilityUnit?: ?AccessibilityUnit, + accessibilityUnit?: ?Stringish, accessibilityValue?: ?AccessibilityValue, /** diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java index 5d25a0bfe3e4f2..ee6ab32496e6fc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java @@ -318,12 +318,6 @@ public void setViewState(@NonNull T view, @Nullable ReadableMap accessibilitySta } } - @Override - @ReactProp(name = ViewProps.ACCESSIBILITY_UNIT) - public void setAccessibilityUnit(@NonNull T view, @Nullable ReadableMap accessibilityUnit) { - // do nothing - } - private void updateViewContentDescription(@NonNull T view) { final String accessibilityLabel = (String) view.getTag(R.id.accessibility_label); final ReadableMap accessibilityState = (ReadableMap) view.getTag(R.id.accessibility_state); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java index d163a5209e5622..afd33e22eb1ba5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerAdapter.java @@ -42,9 +42,6 @@ public void setAccessibilityCollectionItem( @Override public void setViewState(@NonNull T view, @Nullable ReadableMap accessibilityState) {} - @Override - public void setAccessibilityUnit(@NonNull T view, @Nullable ReadableMap accessibilityUnit) {} - @Override public void setBackgroundColor(@NonNull T view, int backgroundColor) {} diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerInterface.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerInterface.java index 435b4c3b499f72..0a6a9a561d5c61 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerInterface.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerInterface.java @@ -34,8 +34,6 @@ public interface BaseViewManagerInterface { void setViewState(T view, @Nullable ReadableMap accessibilityState); - void setAccessibilityUnit(T view, @Nullable ReadableMap accessibilityUnit); - void setBackgroundColor(T view, int backgroundColor); void setBorderRadius(T view, float borderRadius); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java index 738b8ced4ac277..4f4f726095bdf8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java @@ -184,13 +184,6 @@ private static void buildSpannedFromShadowNode( ops.add( new SetSpanOperation(start, end, new ReactClickableSpan(textShadowNode.getReactTag()))); } - if (textShadowNode.mAccessibilityUnit != null && Build.VERSION.SDK_INT >= 21) { - /* - ops.add( - new SetSpanOperation( - start, end, new ReactTtsSpan.Builder(textShadowNode.mAccessibilityUnit).build())); - */ - } float effectiveLetterSpacing = textAttributes.getEffectiveLetterSpacing(); if (!Float.isNaN(effectiveLetterSpacing) && (parentTextAttributes == null @@ -517,13 +510,6 @@ public void setIsAccessibilityLink(@Nullable String accessibilityRole) { } } - @ReactProp(name = "accessibilityUnit") - public void setAccessibilityUnit(@Nullable String accessibilityUnit) { - if (isVirtual()) { - markUpdated(); - } - } - @ReactProp(name = ViewProps.FONT_FAMILY) public void setFontFamily(@Nullable String fontFamily) { mFontFamily = fontFamily; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java index 7e4c66e3a87468..dc874023c58425 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java @@ -12,14 +12,11 @@ import android.text.Spannable; import android.text.TextUtils; import android.text.util.Linkify; -import android.util.Log; import android.view.Gravity; import android.view.View; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.facebook.common.logging.FLog; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; -import com.facebook.react.bridge.ReadableMap; import com.facebook.react.uimanager.BaseViewManager; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.Spacing; @@ -51,13 +48,6 @@ public void setAccessible(ReactTextView view, boolean accessible) { view.setFocusable(accessible); } - @Override - @ReactProp(name = ViewProps.ACCESSIBILITY_UNIT) - public void setAccessibilityUnit(@NonNull T view, @Nullable ReadableMap accessibilityUnit) { - Log.w("TESTING::ReactTextAnchorViewManager", "setAccessibilityUnit"); - Log.w("TESTING::ReactTextAnchorViewManager", "accessibilityUnit: " + (accessibilityUnit)); - } - // maxLines can only be set in master view (block), doesn't really make sense to set in a span @ReactProp(name = ViewProps.NUMBER_OF_LINES, defaultInt = ViewDefaults.NUMBER_OF_LINES) public void setNumberOfLines(ReactTextView view, int numberOfLines) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java index 6ac85573a31337..651de3eb6c3bb4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java @@ -53,6 +53,7 @@ public class TextAttributeProps { public static final short TA_KEY_IS_HIGHLIGHTED = 20; public static final short TA_KEY_LAYOUT_DIRECTION = 21; public static final short TA_KEY_ACCESSIBILITY_ROLE = 22; + public static final short TA_KEY_ACCESSIBILITY_UNIT = 47; public static final int UNSET = -1; @@ -104,6 +105,7 @@ public class TextAttributeProps { protected boolean mIsAccessibilityRoleSet = false; protected @Nullable String mAccessibilityUnit = null; protected boolean mIsAccessibilityLink = false; + protected boolean mIsAccessibilityTtsSpan = false; protected int mFontStyle = UNSET; protected int mFontWeight = UNSET; @@ -206,6 +208,9 @@ public static TextAttributeProps fromMapBuffer(MapBuffer props) { case TA_KEY_ACCESSIBILITY_ROLE: result.setAccessibilityRole(entry.getStringValue()); break; + case TA_KEY_ACCESSIBILITY_UNIT: + result.setAccessibilityUnit(entry.getStringValue()); + break; } } @@ -607,13 +612,15 @@ private void setAccessibilityRole(@Nullable String accessibilityRole) { mIsAccessibilityLink = mAccessibilityRole.equals(AccessibilityRole.LINK); String roleClassName = AccessibilityRole.getValue(AccessibilityRole.fromValue(accessibilityRole)); - mAccessibilityUnit = - ReactTtsSpan.SUPPORTED_UNIT_TYPES.contains(roleClassName) ? roleClassName : null; + mIsAccessibilityTtsSpan = + ReactTtsSpan.SUPPORTED_UNIT_TYPES.contains(roleClassName) && Build.VERSION.SDK_INT >= 21; } } private void setAccessibilityUnit(@Nullable String accessibilityUnit) { - // not yet implemented + if (accessibilityUnit != null) { + mAccessibilityUnit = accessibilityUnit; + } } public static int getTextBreakStrategy(@Nullable String textBreakStrategy) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java index ed321a89bfef2c..8b0eec43c15ef4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java @@ -143,10 +143,22 @@ private static void buildSpannableFromFragment( if (textAttributes.mIsAccessibilityLink) { ops.add(new SetSpanOperation(start, end, new ReactClickableSpan(reactTag))); } - if (textAttributes.mAccessibilityUnit != null && Build.VERSION.SDK_INT >= 21) { + if (textAttributes.mIsAccessibilityTtsSpan) { + // check that textAttributes.mAccessibilityRole == "time" ReactTtsSpan.Builder builder = new ReactTtsSpan.Builder(ReactTtsSpan.TYPE_TIME); - builder.setIntArgument(ReactTtsSpan.ARG_HOURS, 10); - builder.setIntArgument(ReactTtsSpan.ARG_MINUTES, 30); + if (textAttributes.mAccessibilityUnit != null) { + String[] time = textAttributes.mAccessibilityUnit.split(":"); + if (time[0] != null && time[1] != null) { + try { + Integer hours = Integer.parseInt(time[0]); + Integer minutes = Integer.parseInt(time[1]); + builder.setIntArgument(ReactTtsSpan.ARG_HOURS, hours); + builder.setIntArgument(ReactTtsSpan.ARG_MINUTES, minutes); + } catch (Exception e) { + FLog.w(TAG, "TtsSpan with type Time failed to set hours and minutes. Error: " + e); + } + } + } ops.add(new SetSpanOperation(start, end, builder.build())); } if (textAttributes.mIsColorSet) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt index 0f5dd3fcb03b5d..7218daf70cf9d7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt @@ -6,7 +6,7 @@ */ package com.facebook.react.views.view -import android.util.Log; + import android.graphics.Color import android.graphics.Rect import androidx.core.view.ViewCompat @@ -64,7 +64,6 @@ object ReactMapBufferPropSetter { private const val VP_POINTER_OVER_CAPTURE = 44 private const val VP_BORDER_CURVES = 45 // iOS only private const val VP_FG_COLOR = 46 // iOS only? - private const val VP_ACCESSIBILITY_UNIT = 47 // Yoga values private const val YG_BORDER_WIDTH = 100 @@ -108,7 +107,6 @@ object ReactMapBufferPropSetter { private const val UNDEF_COLOR = Int.MAX_VALUE fun setProps(view: ReactViewGroup, viewManager: ReactViewManager, props: MapBuffer) { - Log.w("TESTING::ReactMapBufferPropSetter", "props: " + ( props )); for (entry in props) { when (entry.key) { VP_ACCESSIBILITY_ACTIONS -> { @@ -132,9 +130,6 @@ object ReactMapBufferPropSetter { VP_ACCESSIBILITY_STATE -> { viewManager.accessibilityState(view, entry.mapBufferValue) } - VP_ACCESSIBILITY_UNIT -> { - // viewManager.accessibilityUnit(view, entry.mapBufferValue) - } VP_ACCESSIBILITY_VALUE -> { viewManager.accessibilityValue(view, entry.stringValue) } @@ -283,14 +278,6 @@ object ReactMapBufferPropSetter { ViewCompat.setAccessibilityLiveRegion(this, mode) } - private fun ReactViewManager.accessibilityUnit(view: ReactViewGroup, value: MapBuffer) { - Log.w("TESTING::ReactMapBufferPropSetter", "accessibilityUnit"); - val accessibilityUnit = JavaOnlyMap() - accessibilityUnit.putString("hours", "10") - - setAccessibilityUnit(view, accessibilityUnit) - } - private fun ReactViewManager.accessibilityState(view: ReactViewGroup, value: MapBuffer) { val accessibilityState = JavaOnlyMap() accessibilityState.putBoolean("selected", value.getBoolean(ACCESSIBILITY_STATE_SELECTED)) diff --git a/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp b/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp index 24f5bbd07b8072..741dcc85d4647f 100644 --- a/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp +++ b/ReactCommon/react/renderer/attributedstring/TextAttributes.cpp @@ -98,6 +98,8 @@ void TextAttributes::apply(TextAttributes textAttributes) { accessibilityRole = textAttributes.accessibilityRole.has_value() ? textAttributes.accessibilityRole : accessibilityRole; + accessibilityUnit = !textAttributes.accessibilityUnit.empty() ? textAttributes.accessibilityUnit + : accessibilityUnit; } #pragma mark - Operators @@ -122,6 +124,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const { isHighlighted, layoutDirection, accessibilityRole, + accessibilityUnit, textTransform) == std::tie( rhs.foregroundColor, @@ -142,6 +145,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const { rhs.isHighlighted, rhs.layoutDirection, rhs.accessibilityRole, + rhs.accessibilityUnit, rhs.textTransform) && floatEquality(opacity, rhs.opacity) && floatEquality(fontSize, rhs.fontSize) && @@ -209,6 +213,7 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const { debugStringConvertibleItem("isHighlighted", isHighlighted), debugStringConvertibleItem("layoutDirection", layoutDirection), debugStringConvertibleItem("accessibilityRole", accessibilityRole), + debugStringConvertibleItem("accessibilityUnit", accessibilityUnit), }; } #endif diff --git a/ReactCommon/react/renderer/attributedstring/TextAttributes.h b/ReactCommon/react/renderer/attributedstring/TextAttributes.h index 69400f2ed172f7..017e2d38e16ba9 100644 --- a/ReactCommon/react/renderer/attributedstring/TextAttributes.h +++ b/ReactCommon/react/renderer/attributedstring/TextAttributes.h @@ -79,6 +79,7 @@ class TextAttributes : public DebugStringConvertible { // construction. std::optional layoutDirection{}; std::optional accessibilityRole{}; + std::string accessibilityUnit{}; #pragma mark - Operations @@ -131,7 +132,8 @@ struct hash { textAttributes.textShadowColor, textAttributes.isHighlighted, textAttributes.layoutDirection, - textAttributes.accessibilityRole); + textAttributes.accessibilityRole, + textAttributes.accessibilityUnit); } }; } // namespace std diff --git a/ReactCommon/react/renderer/attributedstring/conversions.h b/ReactCommon/react/renderer/attributedstring/conversions.h index 857b37a673eb28..a3433c4b2ecdb2 100644 --- a/ReactCommon/react/renderer/attributedstring/conversions.h +++ b/ReactCommon/react/renderer/attributedstring/conversions.h @@ -1009,6 +1009,10 @@ inline folly::dynamic toDynamic(const TextAttributes &textAttributes) { _textAttributes( "accessibilityRole", toString(*textAttributes.accessibilityRole)); } + if (!textAttributes.accessibilityUnit.empty()) { + _textAttributes( + "accessibilityUnit", textAttributes.accessibilityUnit); + } return _textAttributes; } @@ -1083,6 +1087,7 @@ constexpr static MapBuffer::Key TA_KEY_IS_HIGHLIGHTED = 20; constexpr static MapBuffer::Key TA_KEY_LAYOUT_DIRECTION = 21; constexpr static MapBuffer::Key TA_KEY_ACCESSIBILITY_ROLE = 22; constexpr static MapBuffer::Key TA_KEY_LINE_BREAK_STRATEGY = 23; +constexpr static MapBuffer::Key TA_KEY_ACCESSIBILITY_UNIT = 47; // constants for ParagraphAttributes serialization constexpr static MapBuffer::Key PA_KEY_MAX_NUMBER_OF_LINES = 0; @@ -1229,6 +1234,10 @@ inline MapBuffer toMapBuffer(const TextAttributes &textAttributes) { builder.putString( TA_KEY_ACCESSIBILITY_ROLE, toString(*textAttributes.accessibilityRole)); } + if (!textAttributes.accessibilityUnit.empty()) { + builder.putString( + TA_KEY_ACCESSIBILITY_UNIT, textAttributes.accessibilityUnit); + } return builder.build(); } diff --git a/ReactCommon/react/renderer/components/text/BaseTextProps.cpp b/ReactCommon/react/renderer/components/text/BaseTextProps.cpp index 6f4741ba69c9ee..e1bac7373c955e 100644 --- a/ReactCommon/react/renderer/components/text/BaseTextProps.cpp +++ b/ReactCommon/react/renderer/components/text/BaseTextProps.cpp @@ -177,6 +177,13 @@ static TextAttributes convertRawProp( sourceTextAttributes.accessibilityRole, defaultTextAttributes.accessibilityRole); + textAttributes.accessibilityUnit = convertRawProp( + context, + rawProps, + "accessibilityUnit", + sourceTextAttributes.accessibilityUnit, + defaultTextAttributes.accessibilityUnit); + // Color (accessed in this order by ViewProps) textAttributes.opacity = convertRawProp( context, @@ -287,6 +294,12 @@ void BaseTextProps::setProp( textAttributes, accessibilityRole, "accessibilityRole"); + REBUILD_FIELD_SWITCH_CASE( + defaults, + value, + textAttributes, + accessibilityUnit, + "accessibilityUnit"); REBUILD_FIELD_SWITCH_CASE( defaults, value, textAttributes, opacity, "opacity"); REBUILD_FIELD_SWITCH_CASE( diff --git a/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h b/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h index 3fed2e90f9d168..abc5df00883946 100644 --- a/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h +++ b/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h @@ -88,22 +88,6 @@ constexpr bool operator!=( return !(rhs == lhs); } -struct AccessibilityUnit { - std::optional hours; -}; - -constexpr bool operator==( - AccessibilityUnit const &lhs, - AccessibilityUnit const &rhs) { - return lhs.hours == rhs.hours; -} - -constexpr bool operator!=( - AccessibilityUnit const &lhs, - AccessibilityUnit const &rhs) { - return !(rhs == lhs); -} - struct AccessibilityLabelledBy { std::vector value{}; }; diff --git a/ReactCommon/react/renderer/components/view/AccessibilityProps.h b/ReactCommon/react/renderer/components/view/AccessibilityProps.h index 387245325f24ab..5656d52affcb53 100644 --- a/ReactCommon/react/renderer/components/view/AccessibilityProps.h +++ b/ReactCommon/react/renderer/components/view/AccessibilityProps.h @@ -39,7 +39,7 @@ class AccessibilityProps { bool accessible{false}; AccessibilityState accessibilityState; - AccessibilityUnit accessibilityUnit; + std::string accessibilityUnit; std::string accessibilityLabel{""}; AccessibilityLabelledBy accessibilityLabelledBy{}; AccessibilityLiveRegion accessibilityLiveRegion{ diff --git a/ReactCommon/react/renderer/components/view/AccessibilityPropsMapBuffer.cpp b/ReactCommon/react/renderer/components/view/AccessibilityPropsMapBuffer.cpp index 191dce6c7b21f9..9107059ccf04be 100644 --- a/ReactCommon/react/renderer/components/view/AccessibilityPropsMapBuffer.cpp +++ b/ReactCommon/react/renderer/components/view/AccessibilityPropsMapBuffer.cpp @@ -46,7 +46,6 @@ constexpr MapBuffer::Key ACCESSIBILITY_STATE_DISABLED = 1; constexpr MapBuffer::Key ACCESSIBILITY_STATE_EXPANDED = 2; constexpr MapBuffer::Key ACCESSIBILITY_STATE_SELECTED = 3; constexpr MapBuffer::Key ACCESSIBILITY_STATE_CHECKED = 4; -constexpr MapBuffer::Key ACCESSIBILITY_UNIT_HOURS = 5; MapBuffer convertAccessibilityState(AccessibilityState const &state) { MapBufferBuilder builder(5); @@ -73,12 +72,6 @@ MapBuffer convertAccessibilityState(AccessibilityState const &state) { return builder.build(); } -MapBuffer convertAccessibilityUnit(AccessibilityUnit const &state) { - MapBufferBuilder builder(1); - builder.putString(ACCESSIBILITY_UNIT_HOURS, "10"); - return builder.build(); -} - // TODO: Currently unsupported: nextFocusForward/Left/Up/Right/Down void AccessibilityProps::propsDiffMapBuffer( Props const *oldPropsPtr, @@ -141,9 +134,9 @@ void AccessibilityProps::propsDiffMapBuffer( } if (oldProps.accessibilityUnit != newProps.accessibilityUnit) { - builder.putMapBuffer( + builder.putString( AP_ACCESSIBILITY_UNIT, - convertAccessibilityUnit(newProps.accessibilityUnit)); + newProps.accessibilityUnit); } if (oldProps.accessibilityValue != newProps.accessibilityValue) { diff --git a/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h b/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h index d2ce04e9319ca2..6659e9d7104db3 100644 --- a/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h +++ b/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h @@ -170,17 +170,6 @@ inline void fromRawValue( } } -inline void fromRawValue( - const PropsParserContext &context, - const RawValue &value, - AccessibilityUnit &result) { - auto map = (butter::map)value; - auto hours = map.find("hours"); - if (hours != map.end()) { - fromRawValue(context, hours->second, result.hours); - } -} - inline std::string toString( const ImportantForAccessibility &importantForAccessibility) { switch (importantForAccessibility) { diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js index a42b43dce995d0..cb36f060077b30 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js @@ -172,7 +172,7 @@ class AccessibilityExample extends React.Component<{}> { My number is 17:00