Accessibility
VirtualizedList from @prepared911/ui/virtualized-list keeps every row in the accessibility tree. The browser skips layout and paint for rows outside the viewport; it does not unmount them. The component owns the list semantics, the scroll region, and scroll-into-view when focus moves to a skipped row. You name the region, write the row content, and announce paging.
ul with role="list" and one li per item. Do not set a role on the row content.Scrollable exposes a role="region" tab stop. Pass scrollRegionLabel so that region has a name.scrollRegionLabel whenever the list scrolls and the rows themselves are not focusable.getItemKey when rows insert or reorder, so focus and state stay on the same item.loadingRow and errorRow are content you render. Put a polite live region on a loading row and an assertive error, with a retry control, when a page fails.--space-4 of overflow margin, which covers the focus ring's offset plus its width.scrollToIndex and scrollToOffset move the scrollport from a button or other control. VirtualizedListAlign.Start and End land the row clear of the edge fade.role="list" on the ul (kept even when the list has no markers).li per item. renderItem returns the row's content, not another list item.aria-posinset or aria-setsize. Every row is present, so the list's count is the DOM's count.