Skip to content

Commit

Permalink
chore: add example of node ref usage
Browse files Browse the repository at this point in the history
  • Loading branch information
remilry committed Feb 16, 2024
1 parent 107ad42 commit ffdeb5d
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 23 deletions.
42 changes: 28 additions & 14 deletions packages/example/src/modules/program/view/ProgramNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,39 @@ 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;
onSelect?: () => void;
indexRange?: [number, number];
};

export const ProgramNode = ({ programInfo, onSelect, indexRange }: Props) => {
return (
<SpatialNavigationNode isFocusable onSelect={onSelect} indexRange={indexRange}>
{({ isFocused }) => <Program isFocused={isFocused} programInfo={programInfo} />}
</SpatialNavigationNode>
);
};
export const ProgramNode = forwardRef<SpatialNavigationNodeRef, Props>(
({ programInfo, onSelect, indexRange }: Props, ref) => {
return (
<SpatialNavigationNode isFocusable onSelect={onSelect} indexRange={indexRange} ref={ref}>
{({ isFocused }) => <Program isFocused={isFocused} programInfo={programInfo} />}
</SpatialNavigationNode>
);
},
);
ProgramNode.displayName = 'ProgramNode';

export const LongProgramNode = ({ programInfo, onSelect, indexRange }: Props) => {
return (
<SpatialNavigationNode isFocusable onSelect={onSelect} alignInGrid indexRange={indexRange}>
{({ isFocused }) => <LongProgram isFocused={isFocused} programInfo={programInfo} />}
</SpatialNavigationNode>
);
};
export const LongProgramNode = forwardRef<SpatialNavigationNodeRef, Props>(
({ programInfo, onSelect, indexRange }: Props, ref) => {
return (
<SpatialNavigationNode
isFocusable
onSelect={onSelect}
alignInGrid
indexRange={indexRange}
ref={ref}
>
{({ isFocused }) => <LongProgram isFocused={isFocused} programInfo={programInfo} />}
</SpatialNavigationNode>
);
},
);
LongProgramNode.displayName = 'LongProgramNode';
49 changes: 40 additions & 9 deletions packages/example/src/pages/GridWithLongNodesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<SpatialNavigationNodeRef>(null);
const lastItemRef = useRef<SpatialNavigationNodeRef>(null);

return (
<Page>
<CenteringView>
Expand All @@ -22,8 +28,9 @@ export const GridWithLongNodesPage = () => {
<SpatialNavigationNode alignInGrid>
<DefaultFocus>
<>
<FirstRow />
<SecondRow />
<FirstRow ref={firstItemRef} />
<SecondRow ref={lastItemRef} />
<ButtonRow firstItemRef={firstItemRef} lastItemRef={lastItemRef} />
</>
</DefaultFocus>
</SpatialNavigationNode>
Expand All @@ -34,32 +41,56 @@ export const GridWithLongNodesPage = () => {
);
};

const FirstRow = () => {
const FirstRow = forwardRef<SpatialNavigationNodeRef>((_, ref) => {
return (
<SpatialNavigationNode orientation="horizontal">
<ListContainer>
<LongProgramNode programInfo={programInfos[0]} indexRange={[0, 1]} />
<LongProgramNode programInfo={programInfos[0]} indexRange={[0, 1]} ref={ref} />
<ProgramNode programInfo={programInfos[1]} indexRange={[2, 2]} />
<ProgramNode programInfo={programInfos[2]} indexRange={[3, 3]} />
<LongProgramNode programInfo={programInfos[3]} indexRange={[4, 5]} />
<ProgramNode programInfo={programInfos[4]} indexRange={[6, 6]} />
</ListContainer>
</SpatialNavigationNode>
);
};
});
FirstRow.displayName = 'FirstRow';

const SecondRow = () => {
const SecondRow = forwardRef<SpatialNavigationNodeRef>((_, ref) => {
const programs = programInfos.slice(6, 13);
return (
<SpatialNavigationNode orientation="horizontal">
<ListContainer>
{/* <LongProgramNode programInfo={programInfos[0]} indexRange={[0, 1]} /> */}
{programs.map((program) => {
return <ProgramNode programInfo={program} key={program.id} />;
{programs.map((program, index) => {
return (
<ProgramNode
programInfo={program}
key={program.id}
ref={index === programs.length - 1 ? ref : null}
/>
);
})}
</ListContainer>
</SpatialNavigationNode>
);
});
SecondRow.displayName = 'SecondRow';

const ButtonRow = ({
firstItemRef,
lastItemRef,
}: {
firstItemRef: MutableRefObject<SpatialNavigationNodeRef>;
lastItemRef: MutableRefObject<SpatialNavigationNodeRef>;
}) => {
return (
<SpatialNavigationNode orientation="horizontal">
<ListContainer>
<Button label="Go to first item" onSelect={() => firstItemRef.current.focus()} />
<Button label="Go to last item" onSelect={() => lastItemRef.current.focus()} />
</ListContainer>
</SpatialNavigationNode>
);
};

const ListContainer = styled.View(({ theme }) => ({
Expand Down

0 comments on commit ffdeb5d

Please sign in to comment.