diff --git a/docs/api.md b/docs/api.md index 3a6f5bce..b35a7fb1 100644 --- a/docs/api.md +++ b/docs/api.md @@ -55,6 +55,12 @@ The `SpatialNavigationNode` component receives the following props: | `indexRange` | `number[]` | `undefined` | Determines the indexes when using long nodes in a grid. If a grid row has one `indexRange`, you should specify each element's `indexRange`. You can check for more details in [`GridWithLongNodesPage`](https://github.com/bamlab/react-tv-space-navigation/blob/31bfe1def4a7e18e9e41f26a520090d1b7a5b149/packages/example/src/pages/GridWithLongNodesPage.tsx) example or in [lrud documentation](https://github.com/bbc/lrud/blob/master/docs/usage.md#indexrange). | | `children` | `({ isFocused, isActive }: { isFocused: boolean, isActive: boolean }) => ReactNode` or `ReactNode` | `null` | Child elements of the component. It can be a function that returns a React element and accepts a parameter with a `isFocused` property when `isFocusable` is `true`. If `isFocusable` is `false` or not provided, it can be any valid React node. | +The `SpatialNavigationNode` component ref expose the following methods: + +| Name | Type | Description | +| ----------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `focus` | `function` | Give the focus to the selected node. | + ## Usage ```jsx diff --git a/packages/example/src/modules/program/view/ProgramNode.tsx b/packages/example/src/modules/program/view/ProgramNode.tsx index e97608fc..2d53a048 100644 --- a/packages/example/src/modules/program/view/ProgramNode.tsx +++ b/packages/example/src/modules/program/view/ProgramNode.tsx @@ -3,6 +3,8 @@ import { SpatialNavigationNode } from 'react-tv-space-navigation'; import { ProgramInfo } from '../domain/programInfo'; import { Program } from './Program'; import { LongProgram } from './LongProgram'; +import { forwardRef } from 'react'; +import { SpatialNavigationNodeRef } from '../../../../../lib/src/spatial-navigation/types/SpatialNavigationNodeRef'; type Props = { programInfo: ProgramInfo; @@ -10,18 +12,30 @@ type Props = { indexRange?: [number, number]; }; -export const ProgramNode = ({ programInfo, onSelect, indexRange }: Props) => { - return ( - - {({ isFocused }) => } - - ); -}; +export const ProgramNode = forwardRef( + ({ programInfo, onSelect, indexRange }: Props, ref) => { + return ( + + {({ isFocused }) => } + + ); + }, +); +ProgramNode.displayName = 'ProgramNode'; -export const LongProgramNode = ({ programInfo, onSelect, indexRange }: Props) => { - return ( - - {({ isFocused }) => } - - ); -}; +export const LongProgramNode = forwardRef( + ({ programInfo, onSelect, indexRange }: Props, ref) => { + return ( + + {({ isFocused }) => } + + ); + }, +); +LongProgramNode.displayName = 'LongProgramNode'; diff --git a/packages/example/src/pages/GridWithLongNodesPage.tsx b/packages/example/src/pages/GridWithLongNodesPage.tsx index 9135dcf2..d46e6a46 100644 --- a/packages/example/src/pages/GridWithLongNodesPage.tsx +++ b/packages/example/src/pages/GridWithLongNodesPage.tsx @@ -10,10 +10,16 @@ import styled from '@emotion/native'; import { scaledPixels } from '../design-system/helpers/scaledPixels'; import { LongProgramNode, ProgramNode } from '../modules/program/view/ProgramNode'; import { theme } from '../design-system/theme/theme'; +import { MutableRefObject, forwardRef, useRef } from 'react'; +import { Button } from '../design-system/components/Button'; +import { SpatialNavigationNodeRef } from '../../../lib/src/spatial-navigation/types/SpatialNavigationNodeRef'; const HEADER_SIZE = scaledPixels(400); export const GridWithLongNodesPage = () => { + const firstItemRef = useRef(null); + const lastItemRef = useRef(null); + return ( @@ -22,8 +28,9 @@ export const GridWithLongNodesPage = () => { <> - - + + + @@ -34,11 +41,11 @@ export const GridWithLongNodesPage = () => { ); }; -const FirstRow = () => { +const FirstRow = forwardRef((_, ref) => { return ( - + @@ -46,20 +53,44 @@ const FirstRow = () => { ); -}; +}); +FirstRow.displayName = 'FirstRow'; -const SecondRow = () => { +const SecondRow = forwardRef((_, ref) => { const programs = programInfos.slice(6, 13); return ( - {/* */} - {programs.map((program) => { - return ; + {programs.map((program, index) => { + return ( + + ); })} ); +}); +SecondRow.displayName = 'SecondRow'; + +const ButtonRow = ({ + firstItemRef, + lastItemRef, +}: { + firstItemRef: MutableRefObject; + lastItemRef: MutableRefObject; +}) => { + return ( + + +