# Video Feed

Video Feed — Legend List documentation.

Source: https://legend.so/list/v3/react/examples/video-feed/

Legend List v3 documentation. Current documentation version.

Features used

-   `onEndReached` to append more clips as the viewer approaches the end of the feed.

example-web/src/examples/VideoFeedExample.tsx

[View source in legend-list](https://github.com/LegendApp/legend-list/blob/a71f2cf68b30061f72bc0735b1326c6a21e2f762/example-web/src/examples/VideoFeedExample.tsx)

```tsx
import React from "react";

import { LegendList } from "@legendapp/list/react";
import { buildVideoFeed, type VideoClip } from "@examples/media";
import { CARD_CLASS, cardStyle, listViewportStyle, Shell } from "./shared";

const initialVideoClips = buildVideoFeed();

export function VideoFeedExample() {
    const [clips, setClips] = React.useState(() => initialVideoClips);
    const [selectedId, setSelectedId] = React.useState(initialVideoClips[0]?.id);
    const viewportRef = React.useRef<HTMLDivElement | null>(null);
    const [viewportHeight, setViewportHeight] = React.useState(0);
    const handleCardKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLButtonElement>, id: string) => {
        if (event.key === "Enter" || event.key === " ") {
            event.preventDefault();
            setSelectedId(id);
        }
    }, []);

    React.useEffect(() => {
        const element = viewportRef.current;
        if (!element) {
            return;
        }

        const update = () => {
            setViewportHeight(Math.max(0, Math.floor(element.getBoundingClientRect().height)));
        };

        update();

        const observer = new ResizeObserver(update);
        observer.observe(element);

        return () => observer.disconnect();
    }, []);

    return (
        <Shell title="Video Feed">
            <div className="flex min-h-0 flex-1" ref={viewportRef}>
                {viewportHeight > 0 ? (
                    <LegendList
                        data={clips}
                        estimatedItemSize={viewportHeight}
                        keyExtractor={(item) => item.id}
                        onEndReached={() => {
                            setClips((current) => buildVideoFeed(current.length + 12).slice(0, current.length + 12));
                        }}
                        recycleItems
                        renderItem={({ item }: { item: VideoClip }) => (
                            <div
                                className="box-border pb-3"
                                style={{
                                    height: viewportHeight,
                                }}
                            >
                                <button
                                    className={`${CARD_CLASS} mb-0 flex h-full w-full flex-col justify-end border-0 text-left text-white cursor-pointer`}
                                    onClick={() => setSelectedId(item.id)}
                                    onKeyDown={(event) => handleCardKeyDown(event, item.id)}
                                    style={{
                                        ...cardStyle(item.color),
                                    }}
                                    type="button"
                                >
                                    <div className="opacity-80">{item.creator}</div>
                                    <div className="text-[26px] font-extrabold">{item.title}</div>
                                    <div className="mt-2 opacity-[0.85]">
                                        {selectedId === item.id ? "Playing" : "Tap to focus"}
                                    </div>
                                </button>
                            </div>
                        )}
                        style={listViewportStyle}
                    />
                ) : null}
            </div>
        </Shell>
    );
}
```

[View Markdown](https://legend.so/list/v3/react/examples/video-feed.md)[Report a documentation correction](https://github.com/LegendApp/legend-docs/issues/new?title=Docs%3A+Video+Feed&body=Page%3A+https%3A%2F%2Flegend.so%2Flist%2Fv3%2Freact%2Fexamples%2Fvideo-feed%0A%0AWhat+is+incorrect+or+missing%3F%0A%0AExpected+behavior+or+supporting+source%3A%0A)
