@@ -14,10 +14,14 @@ import type { Props as TouchableWithoutFeedbackProps } from '../TouchableWithout
1414import applyNativeMethods from '../../modules/applyNativeMethods' ;
1515import createReactClass from 'create-react-class' ;
1616import ensurePositiveDelayProps from '../Touchable/ensurePositiveDelayProps' ;
17+ import findNodeHandle from '../../exports/findNodeHandle' ;
1718import * as React from 'react' ;
1819import StyleSheet from '../StyleSheet' ;
1920import Touchable from '../Touchable' ;
2021import View from '../View' ;
22+ import UIManager from '../UIManager' ;
23+ import Platform from '../Platform' ;
24+ import TVEventHandler from "../TVEventHandler" ;
2125
2226type Event = Object ;
2327type PressEvent = Object ;
@@ -169,6 +173,10 @@ const TouchableHighlight = ((createReactClass({
169173 componentDidMount : function ( ) {
170174 this . _isMounted = true ;
171175 ensurePositiveDelayProps ( this . props ) ;
176+ // Focus component
177+ if ( Platform . isTV && this . props . hasTVPreferredFocus === true ) {
178+ UIManager . focus ( findNodeHandle ( this ) ) ;
179+ }
172180 } ,
173181
174182 componentWillUnmount : function ( ) {
@@ -187,6 +195,15 @@ const TouchableHighlight = ((createReactClass({
187195 },
188196 */
189197
198+ /**
199+ * Set focus to current element
200+ */
201+ setTVPreferredFocus ( hasTVPreferredFocus ) {
202+ if ( Platform . isTV && hasTVPreferredFocus === true ) {
203+ UIManager . focus ( findNodeHandle ( this ) ) ;
204+ }
205+ } ,
206+
190207 /**
191208 * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
192209 * defined on your component.
@@ -206,11 +223,37 @@ const TouchableHighlight = ((createReactClass({
206223 } ,
207224
208225 touchableHandleFocus : function ( e : Event ) {
209- this . props . onFocus && this . props . onFocus ( e ) ;
226+ if ( Platform . isTV ) {
227+ this . state . focused = true ;
228+ // Keep underlay visible
229+ this . _showUnderlay ( ) ;
230+ // Get tvEvent
231+ const tvEvent = TVEventHandler . getTVEvent ( e ) ;
232+ // Dispatch tvEvent to component
233+ this . props . onFocus && this . props . onFocus ( tvEvent ) ;
234+ // Dispatch tvEvent to all listeners
235+ TVEventHandler . dispatchEvent ( tvEvent ) ;
236+ }
237+ else {
238+ this . props . onFocus && this . props . onFocus ( e ) ;
239+ }
210240 } ,
211241
212242 touchableHandleBlur : function ( e : Event ) {
213- this . props . onBlur && this . props . onBlur ( e ) ;
243+ if ( Platform . isTV ) {
244+ this . state . focused = false ;
245+ // Hide underlay
246+ this . _hideUnderlay ( ) ;
247+ // Get tvEvent
248+ const tvEvent = TVEventHandler . getTVEvent ( e ) ;
249+ // Dispatch tvEvent to component
250+ this . props . onBlur && this . props . onBlur ( tvEvent ) ;
251+ // Dispatch tvEvent to all listeners
252+ TVEventHandler . dispatchEvent ( tvEvent ) ;
253+ }
254+ else {
255+ this . props . onBlur && this . props . onBlur ( e ) ;
256+ }
214257 } ,
215258
216259 touchableHandlePress : function ( e : PressEvent ) {
@@ -262,6 +305,9 @@ const TouchableHighlight = ((createReactClass({
262305 _hideUnderlay : function ( ) {
263306 clearTimeout ( this . _hideTimeout ) ;
264307 this . _hideTimeout = null ;
308+ if ( Platform . isTV && this . state . focused ) {
309+ return ;
310+ }
265311 if ( this . props . testOnly_pressed ) {
266312 return ;
267313 }
@@ -298,7 +344,9 @@ const TouchableHighlight = ((createReactClass({
298344 onKeyDown = { this . touchableHandleKeyEvent }
299345 //isTVSelectable={true}
300346 //tvParallaxProperties={this.props.tvParallaxProperties}
301- //hasTVPreferredFocus={this.props.hasTVPreferredFocus}
347+ hasTVPreferredFocus = { this . props . hasTVPreferredFocus }
348+ onFocus = { this . touchableHandleFocus }
349+ onBlur = { this . touchableHandleBlur }
302350 //nextFocusDown={this.props.nextFocusDown}
303351 //nextFocusForward={this.props.nextFocusForward}
304352 //nextFocusLeft={this.props.nextFocusLeft}
0 commit comments