Tinyrack

VirtualList

크거나 크기가 변하거나 계속 추가되는 collection을 stable key로 가상화해요.

핵심 속성

TRVirtualList<T, K>는 보이는 범위와 overscan만 mount하면서 native scrolling을 유지해요. 항목을 삽입, 제거, 재정렬하거나 다시 측정해도 stable key를 기준으로 보이는 anchor를 같은 위치에 유지해요.

속성설명
Collection전체 items 배열과 stable itemKey를 전달하세요. 길이나 양쪽 끝만 보지 않고 전체 key 순서를 비교해요.
Measurement첫 layout에는 estimateSize를 사용해요. 렌더링된 항목은 ResizeObserver로 측정하고 보이는 anchor를 유지하도록 보정해요.
Focus포커스된 항목은 일반 virtual range를 벗어나도 mount 상태를 유지해요.
Followingfollow="leading"이나 follow="trailing"은 viewport가 해당 edge에 고정된 동안만 새 항목을 따라가요.

모든 child를 mount한 채 사용자 정의 scrollbar 구조가 필요하면 TRScrollArea를 사용하세요. Collection 크기나 동적 측정 때문에 모든 항목을 mount하기 부담스러우면 TRVirtualList를 사용하세요.

설치

pnpm add @tinyrack/ui

긴 줄은 코드 영역 안에서 가로로 스크롤해 확인하세요.

스타일

@import '@tinyrack/ui/components/virtual-list.css';

긴 줄은 코드 영역 안에서 가로로 스크롤해 확인하세요.

가져오기

import { TRVirtualList } from '@tinyrack/ui/components/virtual-list';

긴 줄은 코드 영역 안에서 가로로 스크롤해 확인하세요.

플레이그라운드

사용법

큰 이벤트 로그 고유 링크

각 항목에 오래 유지되는 key를 부여하고 예상 block size와 가까운 값을 전달하세요. 렌더링된 row의 실제 크기를 측정한 뒤 layout을 보정해요.

예시

고정된 streaming output 고유 링크

chat이나 log는 trailing edge에서 시작하고 follow를 trailing으로 설정하세요. edge에 고정된 동안에는 새 output을 따라가지만 위로 scroll하면 중단하고, controller로 edge에 돌아오면 다시 시작해요.

가로 및 RTL collection 고유 링크

axis를 horizontal로 설정하세요. 음수 RTL scroll offset을 보고하는 browser에서도 상속된 text direction에 따라 논리적 leading과 trailing을 탐색해요.

API

API설명
TRVirtualList<T, K>Generic React component예요. items, itemKey, estimateSize, renderItem이 필요하고 axis 기본값은 vertical이에요.
rootProps, viewportProps, itemProps각 public DOM surface에 native div attribute, event, class, style을 전달해요. itemProps는 항목과 index를 받아요.
rootRef, viewportRef, itemRefNative element를 받아요. itemRef에는 element, 항목, index가 전달돼요.
TRVirtualListInitialPosition<K>논리적 edge, stable key, index에서 시작해요. leading, center, trailing, nearest alignment를 선택할 수 있어요.
TRVirtualListSnapshot<K>보이는 anchor와 stable key별 측정 크기를 저장해요. takeSnapshot() 결과를 initialSnapshot에 다시 전달하세요.
TRVirtualListFollownone, leading, trailing 중 하나예요. 선택한 edge에 고정된 동안만 따라가요.
TRVirtualListEdgeRequestleadingEdgeRequesttrailingEdgeRequest는 서로 독립된 requestKey, callback, 측정되는 slot, 타입이 지정된 triggerExtent를 받아요. 같은 key는 해당 edge에서 한 번만 실행되고 기본 범위는 viewport 하나예요.
TRVirtualListTriggerExtent음수가 아닌 유한한 edge 범위를 { kind: 'viewports', value } 또는 { kind: 'pixels', value }로 지정해요.
TRVirtualListRange<K>onVisibleRangeChanged가 보이는 시작·끝 index와 stable key를 알려 줘요. Overscan은 제외해요.
TRVirtualListController<K>scrollToIndex, scrollToKey, scrollToEdge, takeSnapshot, 한 번만 적용되는 holdVisibleAnchorForNextLayout을 제공해요. useTRVirtualListController<K>()로 만드세요.
ssrFallbackServer와 첫 hydration에 표시할 명시적 content예요. Hydration 중 server tree를 바꾸지 않고 이후에 virtual viewport를 mount해요.

scrollToKey에 없는 key를 전달하면 아무 작업도 하지 않아요. Collection update에서 보이는 anchor가 제거되면 다음으로 살아남은 visible key를 fallback으로 사용해요. Disclosure나 streaming row의 크기가 바뀌는 한 번의 layout에서 edge follow 대신 현재 anchor를 유지하려면 변경 전에 holdVisibleAnchorForNextLayout()을 호출하세요.