How to use TVFocusGuideView API in Vega

How to use TVFocusGuideView in a Vega project

In this, we will go through these steps to integrate TVFocusGuideView in a Vega project:

  1. How to integrate TVFocusGuideView library in a Vega project.
  2. Hands-on : TVFocusGuideView API

To help you manage focus in your Vega apps, TVFocusGuideView API is ported in Vega.

Prerequisites:

A working Vega project. If you don’t have a Vega project, you can follow this guide.

  1. Import TVFocusGuideView

import { TVFocusGuideView } from '@amzn/react-native-kepler';

  1. Once imported, now we can start using TVFocusGuideView. It accepts a few props. You can learn about props supported by TVFocusGuideView here.

:laptop: What we will build

To understand TVFocusGuideView, we will create an app (please refer below image) with some requirements (these are arbitrary requirements. It doesn’t mean that app should have these functionalities. We will learn usage of props, and implementation of the TVFocusGuideView)

  1. Focus from side nav should go the main section’s Hero Image on click of Right button. We will use autoFocus props here.

  2. From Hero Image focus should move to grid section, on click of Down button. We will use autoFocus props here.

  3. Focus from grid (1-8) section should not move back to the navigation. We will use trapFocusLeft props here.

  4. Focus should move to About button when moving back from Hero Image. We will use destinations props here.

  5. Focus should not move to Main Section until the focus has reached the last element of the navigation. We will use trapFocusRight props here.

If we do not use TVFocusGuide, there’s no control on the focus & navigation and the above requirements will work like this:

  1. Clicking the RIGHT button on the D-pad will shift the focus to the first “touchable” element, typically within the grid.
  2. Clicking the LEFT button on the D-Pad will direct focus to the side navigation
  3. Pressing the DOWN button on the D-pad will move focus outside the grid, and so forth.

Without TVFocusGuideView

After TVFocusGuideView

Hands-on : TVFocusGuideView API

Requirement 1: Focus should go to the hero image of main section from Home

On click of RIGHT Button, Focus should go to the hero image of main section from Sub Nav (Home button).

To move the focus from side nav to the hero image, we can use autoFocus from tvFocusGuideView. If we don’t use the autoFocus then the focus would skip the Hero Image and go to the the grid. Why? Because focus works on “proximity algorithm”

  1. Wrap the Hero component with tvFocusGuideView
  2. use autoFocus props on the top most wrapper
import React from 'react';
import {Text, TouchableOpacity} from 'react-native';
import {TVFocusGuideView} from '@amzn/react-native-kepler';

const Hero = () => {
  return (
    <TVFocusGuideView autoFocus>
      <Text >This is hero Image</Text>
      <TouchableOpacity>
        <Text>Play Now</Text>
      </TouchableOpacity>
    </TVFocusGuideView>
  );
};

export default Hero;

Requirement 2 : From hero image, focus should go to Grid

<TVFocusGuideView autoFocus>
     <Hero />
     <Grid />
</TVFocusGuideView>

Requirement 3 : Focus should not go to the side-navigation

On Click of LEFT Button on D-pad, the focus should not go to the side-navigation

(Please, refer the below image) when LEFT button is pressed on the 1st and 5th box, the focus should remain in grid.

For this we need trapFocusLeft, if we don’t use trapFocusLeft, the focus will go to navigation from Grid.

import React from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
import {TVFocusGuideView} from '@amzn/react-native-kepler';

const Grid = () => {
  return (
    <View>
      <TVFocusGuideView trapFocusLeft>
        <View>
          <TouchableOpacity>
            <Text>1</Text>
          </TouchableOpacity>
          <TouchableOpacity>
            <Text>2</Text>
          </TouchableOpacity>
          <TouchableOpacity>
            <Text>3</Text>
          </TouchableOpacity>
          <TouchableOpacity>
            <Text>4</Text>
          </TouchableOpacity>
          <TouchableOpacity>
            <Text>5</Text>
          </TouchableOpacity>
        </View>
        <View>
          <TouchableOpacity>
            <Text>6</Text>
          </TouchableOpacity>
          <TouchableOpacity>
            <Text>7</Text>
          </TouchableOpacity>
          <TouchableOpacity>
            <Text>8</Text>
          </TouchableOpacity>
          <TouchableOpacity>
            <Text>9</Text>
          </TouchableOpacity>
          <TouchableOpacity>
            <Text>10</Text>
          </TouchableOpacity>
        </View>
      </TVFocusGuideView>

      <View>
        <TouchableOpacity>
          <Text>Outside Button</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

export default Grid;

Requirement 4: Focus to skip elements when moving back (Just for fun)

On click of Left button , move focus from hero Image to “about” and not to “settings”. To override default previous destinations, you can use destinations props.

import React, {useRef} from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
import {TVFocusGuideView} from '@amzn/react-native-kepler';

const Nav= () => {
  const aboutRef = useRef();
  
  return (
    <TVFocusGuideView
      trapFocusRight
      destinations={[aboutRef.current]}>
      <View>
        <TouchableOpacity >
          <Text>Home</Text>
        </TouchableOpacity>
        <TouchableOpacity ref={aboutRef} style={styles.nav}>
          <Text>About</Text>
        </TouchableOpacity>
        <TouchableOpacity>
          <Text>Live</Text>
        </TouchableOpacity>
        <TouchableOpacity>
          <Text>Settings</Text>
        </TouchableOpacity>
      </View>
    </TVFocusGuideView>
  );
};

export default Nav;

In the above code, we have done the following:

  1. Wrapped the Nav component with TVFocusGuideView
  2. Utilised useRef, to obtain the reference of items.
  3. Utilised destinations props to define the previous elements. Remember, since we are using refs, we need to reference them by b2.current
  4. Test time. Now, press back from hero image and you will observe that focus is going to About and not to the last focused element - settings

:rocket: Demo

Summary:

  1. TV apps follow the focus algorithm on proximity.
  2. TVFocusGuideView API assists in controlling proximity behaviour.
  3. Utilize focusTrap to restrict focus movement. One can choose between - trapFocusRight, trapFocusLeft, trapFocusBottom, trapFocusTop.
  4. Implement autoFocus to programmatically focus on an element/item.
  5. Use destinations to determine the previous focus
  6. Vega documentation