diff --git a/packages/ui-react/src/components/CardGrid/CardGrid.tsx b/packages/ui-react/src/components/CardGrid/CardGrid.tsx index 868628b92..e900a7fe1 100644 --- a/packages/ui-react/src/components/CardGrid/CardGrid.tsx +++ b/packages/ui-react/src/components/CardGrid/CardGrid.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import classNames from 'classnames'; import InfiniteScroll from 'react-infinite-scroller'; import type { Playlist, PlaylistItem } from '@jwp/ott-common/types/playlist'; @@ -46,6 +46,8 @@ export type CardGridProps = { getUrl: (item: PlaylistItem) => string; }; +const getCellKey = (item: PlaylistItem) => item.mediaid; + function CardGrid({ playlist, watchHistory, @@ -75,6 +77,25 @@ function CardGrid({ setRowCount(INITIAL_ROW_COUNT); }, [playlist.feedid]); + const renderCell = useCallback( + (playlistItem: PlaylistItem, tabIndex: number) => ( + onCardHover(playlistItem) : undefined} + loading={isLoading} + isCurrent={currentCardItem && currentCardItem.mediaid === playlistItem.mediaid} + currentLabel={currentCardLabel} + isLocked={isLocked(accessModel, isLoggedIn, hasSubscription, playlistItem)} + posterAspect={posterAspect} + item={playlistItem} + headingLevel={headingLevel} + /> + ), + [accessModel, currentCardItem, currentCardLabel, getUrl, hasSubscription, headingLevel, isLoading, isLoggedIn, onCardHover, posterAspect, watchHistory], + ); + return ( ( - onCardHover(playlistItem) : undefined} - loading={isLoading} - isCurrent={currentCardItem && currentCardItem.mediaid === playlistItem.mediaid} - currentLabel={currentCardLabel} - isLocked={isLocked(accessModel, isLoggedIn, hasSubscription, playlistItem)} - posterAspect={posterAspect} - item={playlistItem} - headingLevel={headingLevel} - /> - )} + renderCell={renderCell} + getCellKey={getCellKey} /> ); diff --git a/packages/ui-react/src/components/LayoutGrid/LayoutGrid.tsx b/packages/ui-react/src/components/LayoutGrid/LayoutGrid.tsx index 385a9abab..3a111f2f9 100644 --- a/packages/ui-react/src/components/LayoutGrid/LayoutGrid.tsx +++ b/packages/ui-react/src/components/LayoutGrid/LayoutGrid.tsx @@ -1,6 +1,6 @@ import { throttle } from '@jwp/ott-common/src/utils/common'; import useEventCallback from '@jwp/ott-hooks-react/src/useEventCallback'; -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import styles from './LayoutGrid.module.scss'; @@ -9,6 +9,7 @@ type Props = { columnCount: number; data: Item[]; renderCell: (item: Item, tabIndex: number) => JSX.Element; + getCellKey: (item: Item, rowIndex: number, columnIndex: number) => string; }; const scrollIntoViewThrottled = throttle(function (focusedElement: HTMLElement) { @@ -16,7 +17,7 @@ const scrollIntoViewThrottled = throttle(function (focusedElement: HTMLElement) }, 300); // Keyboard-accessible grid layout, with focus management -const LayoutGrid = ({ className, columnCount, data, renderCell }: Props) => { +const LayoutGrid = ({ className, columnCount, data, renderCell, getCellKey }: Props) => { const [currentRowIndex, setCurrentRowIndex] = useState(0); const [currentColumnIndex, setCurrentColumnIndex] = useState(0); const gridRef = useRef(null); @@ -110,6 +111,8 @@ const LayoutGrid = ({ className, columnCount, data, renderC // eslint-disable-next-line react-hooks/exhaustive-deps }, [columnCount]); + const gridCellStyle = useMemo(() => ({ width: `${Math.round(100 / columnCount)}%` }), [columnCount]); + return (
{Array.from({ length: rowCount }).map((_, rowIndex) => ( @@ -118,10 +121,10 @@ const LayoutGrid = ({ className, columnCount, data, renderC
{renderCell(item, currentRowIndex === rowIndex && currentColumnIndex === columnIndex ? 0 : -1)}