diff --git a/cspell.json b/cspell.json index 42f68b5116..0310eeacdf 100644 --- a/cspell.json +++ b/cspell.json @@ -33,6 +33,8 @@ ], "words": [ "Figma", + "DoDont", + "dont", "IgniteUI", "Ignite", "DocFX", diff --git a/docs/angular/src/content/en/images/anatomy-content-light/virtual-scroll-lt-a.png b/docs/angular/src/content/en/images/anatomy-content-light/virtual-scroll-lt-a.png new file mode 100644 index 0000000000..5aa26700cb Binary files /dev/null and b/docs/angular/src/content/en/images/anatomy-content-light/virtual-scroll-lt-a.png differ diff --git a/docs/angular/src/content/en/images/virtual-scroll/virtual-scroll-do-not.png b/docs/angular/src/content/en/images/virtual-scroll/virtual-scroll-do-not.png new file mode 100644 index 0000000000..3772d6bce2 Binary files /dev/null and b/docs/angular/src/content/en/images/virtual-scroll/virtual-scroll-do-not.png differ diff --git a/docs/angular/src/content/en/images/virtual-scroll/virtual-scroll-do.png b/docs/angular/src/content/en/images/virtual-scroll/virtual-scroll-do.png new file mode 100644 index 0000000000..8d3349ca03 Binary files /dev/null and b/docs/angular/src/content/en/images/virtual-scroll/virtual-scroll-do.png differ diff --git a/docs/angular/src/content/jp/images/anatomy-content-light/virtual-scroll-lt-a.png b/docs/angular/src/content/jp/images/anatomy-content-light/virtual-scroll-lt-a.png new file mode 100644 index 0000000000..5aa26700cb Binary files /dev/null and b/docs/angular/src/content/jp/images/anatomy-content-light/virtual-scroll-lt-a.png differ diff --git a/docs/angular/src/content/jp/images/virtual-scroll/virtual-scroll-do-not.png b/docs/angular/src/content/jp/images/virtual-scroll/virtual-scroll-do-not.png new file mode 100644 index 0000000000..3772d6bce2 Binary files /dev/null and b/docs/angular/src/content/jp/images/virtual-scroll/virtual-scroll-do-not.png differ diff --git a/docs/angular/src/content/jp/images/virtual-scroll/virtual-scroll-do.png b/docs/angular/src/content/jp/images/virtual-scroll/virtual-scroll-do.png new file mode 100644 index 0000000000..8d3349ca03 Binary files /dev/null and b/docs/angular/src/content/jp/images/virtual-scroll/virtual-scroll-do.png differ diff --git a/docs/xplat/src/assets/images/anatomy-content-light/virtual-scroll-lt-a.png b/docs/xplat/src/assets/images/anatomy-content-light/virtual-scroll-lt-a.png new file mode 100644 index 0000000000..5aa26700cb Binary files /dev/null and b/docs/xplat/src/assets/images/anatomy-content-light/virtual-scroll-lt-a.png differ diff --git a/docs/xplat/src/assets/images/virtual-scroll/virtual-scroll-do-not.png b/docs/xplat/src/assets/images/virtual-scroll/virtual-scroll-do-not.png new file mode 100644 index 0000000000..3772d6bce2 Binary files /dev/null and b/docs/xplat/src/assets/images/virtual-scroll/virtual-scroll-do-not.png differ diff --git a/docs/xplat/src/assets/images/virtual-scroll/virtual-scroll-do.png b/docs/xplat/src/assets/images/virtual-scroll/virtual-scroll-do.png new file mode 100644 index 0000000000..8d3349ca03 Binary files /dev/null and b/docs/xplat/src/assets/images/virtual-scroll/virtual-scroll-do.png differ diff --git a/docs/xplat/src/content/en/components/layouts/virtual-scroll.mdx b/docs/xplat/src/content/en/components/layouts/virtual-scroll.mdx index 8ffc42f3d3..e9870c4e87 100644 --- a/docs/xplat/src/content/en/components/layouts/virtual-scroll.mdx +++ b/docs/xplat/src/content/en/components/layouts/virtual-scroll.mdx @@ -2,19 +2,23 @@ title: "Virtual Scroll" description: "The Virtual Scroll is a component that renders only the items in its viewport plus a small buffer, so large lists scroll smoothly." keywords: "{Platform} Virtual Scroll, virtualization, virtual list, large lists, infinite scroll, remote data, {ProductName}" -last_updated: "2026-09-17" +last_updated: "2026-09-25" license: MIT mentionedTypes: ["VirtualScroll"] -relatedComponents: ["List", "Card"] +relatedComponents: ["List", "Grid", "Card"] llms: description: "The {ProductName} Virtual Scroll is a component that renders large lists by keeping only the items in its viewport, plus a configurable buffer, in the DOM." --- -import DocsAside from 'igniteui-astro-components/components/mdx/DocsAside.astro'; import PlatformBlock from 'igniteui-astro-components/components/mdx/PlatformBlock.astro'; import Sample from 'igniteui-astro-components/components/mdx/Sample.astro'; import ApiLink from 'igniteui-astro-components/components/mdx/ApiLink.astro'; +import Anatomy from 'igniteui-astro-components/components/mdx/Anatomy.astro'; import Faq from 'igniteui-astro-components/components/mdx/Faq.astro'; import FaqItem from 'igniteui-astro-components/components/mdx/FaqItem.astro'; +import { Image } from 'astro:assets'; +import virtualScrollAnatomy from '@xplat-images/anatomy-content-light/virtual-scroll-lt-a.png'; +import virtualScrollDo from '@xplat-images/virtual-scroll/virtual-scroll-do.png'; +import virtualScrollDoNot from '@xplat-images/virtual-scroll/virtual-scroll-do-not.png'; # Virtual Scroll Component @@ -28,7 +32,7 @@ The {ProductName} Virtual Scroll is a component that renders large lists by keep - + @@ -38,7 +42,27 @@ The {ProductName} Virtual Scroll is a component that renders large lists by keep The {Platform} Virtual Scroll renders the visible items plus a configurable buffer, and its track preserves the scroll range of the whole collection. -{/*TODO: add the Virtual Scroll anatomy image and render it with the component.*/} + + + + +1. Host: The scroll container. Its fixed height (width when horizontal) sets how many items are visible.
+2. Track: A spacer sized to the estimated length of the whole collection, so the scrollbar spans every item.
+3. Content element: Holds only the rendered items. It starts at the first rendered buffer item, above the viewport, and takes its size from the rendered items.
+4. Item wrapper: One per rendered item. It hosts the item template and is the box that gets measured.
+5. Over-scan buffer: The overScan items (2 by default) rendered past each edge of the viewport.
@@ -51,7 +75,7 @@ igx-virtual-scroll — scrollable viewport (role="list") - + ```text igc-virtual-scroll — scrollable viewport @@ -115,7 +139,32 @@ virtualScroll.data = Array.from({ length: 100_000 }, (_, i) => ({ name: `Item ${ -The Virtual Scroll host needs a fixed height for vertical scrolling or a fixed width for horizontal scrolling. A host that grows with its content has no viewport to fill. + + +Set up {ProductName} with the [Getting Started](../general-getting-started.mdx) topic, then import the and give it an item template and data. The React wrapper registers the underlying element when the module loads, so no registration call is needed: + +```tsx +import { IgrVirtualScroll } from 'igniteui-react'; +import type { VirtualScrollItemContext } from 'igniteui-react'; + +const items = Array.from({ length: 100_000 }, (_, i) => ({ name: `Item ${i}` })); + +export function Employees() { + return ( + ) => ( +
{ctx.index}: {ctx.value.name}
+ )} + style={{ height: '400px' }} + /> + ); +} +``` + +
+ +The Virtual Scroll host needs a fixed height for vertical scrolling or a fixed width for horizontal scrolling. A host that grows with its content renders every item, so the list is not virtualized. ### Prerequisites and Version Compatibility @@ -139,6 +188,18 @@ The Virtual Scroll host needs a fixed height for vertical scrolling or a fixed w
+ + +| Requirement | Value | +| --- | --- | +| Package | `igniteui-react` (MIT) | +| First release with the component | 19.9.0 | +| Peer packages | `react` and `react-dom` 18 or 19 | +| Item templates | JSX returned from a function. `igniteui-webcomponents` comes in as a dependency of `igniteui-react`; you do not install it yourself. | +| Theme | Import a theme stylesheet once, for example `igniteui-webcomponents/themes/light/bootstrap.css`. | + + + ## Usage ### Item Template @@ -151,7 +212,7 @@ Mark an `ng-template` with `igxVirtualItem`, or pass a template defined elsewher ```html - + @@ -181,6 +242,27 @@ virtualScroll.itemTemplate = (ctx: VirtualScrollItemContext) => html`
+ + +Set to a function that returns JSX. The function receives a `VirtualScrollItemContext` with `value` (the item), `index`, `count`, `isFirst`, and `isLast`. Without an item template, the component renders nothing. + +```tsx +) => ( + + + {ctx.value.name} + {ctx.value.email} + + )} + style={{ height: '480px' }} +/> +``` + + + ### Data The Virtual Scroll collection is compared by reference. Assign a new array to update the list; changing the bound array in place, for example with `push`, does not update it. @@ -201,11 +283,41 @@ virtualScroll.data = [...virtualScroll.data, newEmployee];
+ + +```tsx +setEmployees(current => [...current, newEmployee]); +``` + + + When `data` changes, the component keeps the measured sizes of the items before the first changed index and measures the rest again when they render. Appending keeps every existing measurement; replacing, filtering, or sorting discards the measurements from the first changed item onwards. + + +An item keeps its element while its key is in the rendered window. Without the index is the key, so after a sort, an insert, or a removal the element at an index stays put and shows its new item. Return a stable id from `keyFunction` when items move within `data`: + +```ts +virtualScroll.keyFunction = (employee) => employee.id; +``` + + + ### Estimated Item Size -The Virtual Scroll is the size in pixels an item has until it renders and is measured (`50` by default). Items can have different sizes: each measured size replaces the estimate. Set the estimate close to the average item size to keep the scrollbar and `scrollToIndex` accurate before items are measured. +The Virtual Scroll is the size in pixels an item has until it renders and is measured (`50` by default). Items can have different sizes: each measured size replaces the estimate. + + + +Set the estimate close to the average item size to keep the scrollbar and `scrollToIndex` accurate before items are measured. + + + + + +Set the estimate close to the average item size so that the first render lands near the real content. Once items are measured, their average replaces the estimate for the items that are not measured yet, so the scrollbar and `scrollToIndex` correct themselves even when the estimate is off. + + @@ -227,6 +339,16 @@ The Virtual Scroll + + +```tsx + +``` + + + + + Items are measured by their border box, so margins are not part of an item's size. Space items with padding, or with a `gap` inside the item, instead of margins. ### Orientation @@ -257,6 +379,22 @@ The Virtual Scroll + +```tsx +
...
} + style={{ height: '200px' }} +/> +``` + + + +
+ ### Over-Scan The Virtual Scroll is the number of extra items rendered beyond each edge of the viewport (`2` by default). A larger value reduces blank areas during fast scrolling and renders more elements. @@ -277,6 +415,14 @@ The Virtual Scroll + +```tsx + +``` + + + ### Scroll to Index The Virtual Scroll method scrolls an item into view. Its options are those of the native `scrollIntoView`: `block` (`start`, `center`, `end`, or `nearest`), `inline` for a horizontal list, and `behavior` (`auto` or `smooth`). Items that have not rendered only have an estimated size, so the component measures the items where it lands and corrects the position; the returned promise resolves on the final position. @@ -305,6 +451,20 @@ await virtualScroll.scrollToIndex(index, { block: 'center' }); + + +```tsx +const virtualScroll = useRef(null); + +async function goTo(index: number): Promise { + await virtualScroll.current?.scrollToIndex(index, { block: 'center' }); +} +``` + + + + + With `block: 'nearest'`, the position does not change when the item is already fully visible. Indices outside the collection are clamped to the first or last item. ### Infinite Scroll @@ -350,6 +510,27 @@ virtualScroll.addEventListener('igcDataRequest', (event: CustomEvent + + +The Virtual Scroll `onDataRequest` event supports append-only loading from remote data. It is emitted when the rendered window nears the end of `data`, and on the first render when the loaded items do not fill the viewport. Append the requested items as a new array: + +```tsx +) => { + const { startIndex, count } = event.detail; + const page = await fetchEmployees(startIndex, count); + setEmployees(current => [...current, ...page]); + }} + style={{ height: '440px' }} +/> +``` + + + + + Only one data request is pending at a time; the next one follows the next `data` change. An empty `data` emits no request, so load the first page yourself. When the source has no more items, stop appending: the component does not request the same start index again. @@ -422,32 +603,130 @@ await virtualScroll.layoutComplete; + + +```tsx +setEmployees(await fetchEmployees()); +await virtualScroll.current?.layoutComplete; +``` + + + ### Do/Don't -{/*TODO: add the Virtual Scroll Do/Don't guidance image from Indigo.Design when it is available.*/} +The Virtual Scroll usually works as the scroll container of a long list, keeping only the items in its viewport, plus a small buffer, in the DOM. Avoid it for a list short enough to render at once, and as you write the item template, keep each item state in the data rather than in its elements: item elements are reused, so DOM state the template does not bind shows on whichever item takes the element. + + + +
+
+
+{Platform} Virtual Scroll showing a list of 100,000 employees +
+
+Do + +Use the Virtual Scroll for a long list that is too large to render at once, such as a directory, a feed, a log, or a strip of cards, including lists that load remote data while scrolling. + +
+
+
+
+{Platform} Virtual Scroll used for a list of only five employees +
+
+Don't -**When to use:** Use the Virtual Scroll for a long list that is too large to render at once, such as a directory, a feed, a log, or a strip of cards, including lists that load remote data while scrolling. - -**When not to use:** Render a short list directly with the [List](../list.mdx) and `@for`. Use the [Grid](../grid/grid.mdx) for tabular data with columns, sorting, or filtering. Show a small set of rich items as [Card](../card.mdx) elements without virtualization. +Render a short list directly with the [List](../list.mdx) and `@for`. Use the [{Platform} Data Grid](../grid/grid.mdx) for tabular data with columns, sorting, or filtering. Show a small set of rich items as [Card](../card.mdx) elements without virtualization. - - -**When to use:** Use the Virtual Scroll for a long list that is too large to render at once, such as a directory, a feed, a log, or a strip of cards, including lists that load remote data while scrolling. + -**When not to use:** Render a short list directly with the [List](../grids/list.mdx). Show a small set of rich items as [Card](./card.mdx) elements without virtualization. +Render a short list directly with the [List](../grids/list.mdx). Use the [{Platform} Data Grid](../grids/data-grid.mdx) for tabular data with columns, sorting, or filtering. Show a small set of rich items as [Card](./card.mdx) elements without virtualization. -| Do | Don't | -| --- | --- | -| Give the host a fixed height (vertical) or width (horizontal). | Let the host grow with its content. | -| Set `estimatedItemSize` close to the average item size. | Keep the 50px default for much larger or smaller items. | -| Assign a new array when the collection changes. | Change the bound array in place. | -| Space items with padding or `gap`. | Space items with margins. | +
+
+
## Properties @@ -474,10 +753,25 @@ await virtualScroll.layoutComplete; | | `number` | `2` | Extra items rendered beyond each edge of the viewport. Attribute: `over-scan`. | | | `number` | `50` | The size in pixels of an item until it is measured. A non-positive value uses `50`. Attribute: `estimated-item-size`. | | | `VirtualScrollItemTemplate \| null` | `null` | The function that renders each item. Property only. | +| | `VirtualScrollKeyFunction \| null` | `null` | Returns an item's key, so an item keeps its element when it moves in `data`. Without it, the index is the key. Property only. | | | `Promise` (read-only) | — | Resolves when rendering and item measurement have settled. | + + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| | `any[]` | `[]` | The collection to virtualize. Compared by reference. | +| | `'vertical' \| 'horizontal'` | `'vertical'` | The scroll axis. | +| | `number` | `2` | Extra items rendered beyond each edge of the viewport. | +| | `number` | `50` | The size in pixels of an item until it is measured. A non-positive value uses `50`. | +| | `(ctx: VirtualScrollItemContext) => ReactNode` | `null` | The function that renders each item. | +| | `(item, index) => unknown` | `null` | Returns an item's key, so an item keeps its element when it moves in `data`. Without it, the index is the key. | +| | `Promise` (read-only) | — | Resolves when rendering and item measurement have settled. Read it from a ref, not as a prop. | + + + ## Methods | Name | Returns | Description | @@ -504,6 +798,17 @@ await virtualScroll.layoutComplete; + + +| Name | Argument | Description | +| --- | --- | --- | +| `onStateChange` | `CustomEvent` | Emitted when the rendered window changes. `event.detail` carries `startIndex`, `endIndex`, `viewportSize`, `totalSize`. | +| `onDataRequest` | `CustomEvent` | Emitted when the rendered window nears the end of `data`. `event.detail` carries `startIndex` and `count`. | + +The handlers receive the native `CustomEvent`, so read the payload from `event.detail`. + + + ## Styling The {Platform} Virtual Scroll has no theme of its own: it lays out the viewport, and the rendered items take their styles from the elements and components in the item template. @@ -524,7 +829,7 @@ Size the host and target the rendered items with the classes from the [Anatomy]( - + The component renders into its light DOM, so regular selectors reach the rendered items. Its default styles give the host a height of `18.75rem`; override the height to size the viewport. @@ -555,19 +860,20 @@ The {Platform} Virtual Scroll adds no key handlers. The host is a native scroll | Page Up / Page Down | Scrolls by about one viewport. | | Home / End | Scrolls to the start or the end of the collection. | -The host has no `tabindex`. Browsers differ in whether a scroll container without focusable content can receive focus, so set `tabindex="0"` on the host when the items contain nothing focusable. Items scrolled out of view leave the DOM, so focus inside a removed item is lost. +The host has no `tabindex`. Browsers differ in whether a scroll container without focusable content can receive focus, so set `tabindex="0"` on the host when the items contain nothing focusable. Focus inside an item does not survive that item leaving the rendered window, so move focus deliberately before it does. ### Screen Readers / ARIA - The host has `role="list"`; the track, the content element, and the item wrappers have `role="presentation"`. Items that render `role="listitem"`, such as `igx-list-item`, are exposed as items of that list. +- Inside a container that already provides list semantics, such as `igx-list`, set `role="presentation"` on the host so that the items are not nested in a second list. - Map the `index` and `count` template variables to `aria-posinset` and `aria-setsize`. - Give a focusable host an accessible name with `aria-label` or `aria-labelledby`. - + - The track, the content element, and the item wrappers have `role="presentation"`. The host has no role: place it inside an element with a list role, such as `igc-list`, or give it `role="list"` when the items render `role="listitem"`. - Map the `index` and `count` context properties to `aria-posinset` and `aria-setsize`. @@ -603,7 +909,19 @@ The Virtual Scroll compares `data` by reference, so a change in place is not det ### Why does the scrollbar change size while I scroll? -Items that have not rendered use `estimatedItemSize`, and the total size is corrected as items are measured. Set `estimatedItemSize` close to the average item size. +Items that have not rendered use `estimatedItemSize`, and the total size is corrected as items are measured. + + + +Set `estimatedItemSize` close to the average item size. + + + + + +The average measured size then replaces the estimate for the items that are not measured yet, so the correction settles as you scroll. Set `estimatedItemSize` close to the average item size to make the first render land near the real content. + + ### Why do items drift out of place further down the list? @@ -628,7 +946,7 @@ The Virtual Scroll measures items at runtime and creates its own scroll containe | `igxForScrollContainer` | Not needed: the host is the scroll container | | `scrollTo(index)` | `scrollToIndex(index, options)`, which returns a promise | | `chunkLoad`, `chunkPreload` | `stateChange` | -| `igxForRemote` with `totalItemCount` | `dataWindow` with `totalCount`, or `data` with `dataRequest` for append-only loading | +| `igxForTotalItemCount` for remote data | `dataWindow` with `totalCount`, or `data` with `dataRequest` for append-only loading | | `index`, `count`, `first`, `last`, `even`, `odd` | The same template variables | The grids keep their own row and column virtualization; see [Grid Virtualization](../grid/virtualization.mdx). @@ -638,7 +956,7 @@ The grids keep their own row and column virtualization; see [Grid Virtualization ## Known Limitations - The {Platform} Virtual Scroll virtualizes one axis. Rows and columns that are both virtualized require a grid. -- Items scrolled out of view are removed from the DOM together with their focus and internal state. +- Item elements are reused as the window moves, so DOM state that the item template does not bind, such as a checkbox without a bound `checked`, shows on whichever item takes the element. Bind all item state, and write user changes back to the item. @@ -664,6 +982,12 @@ The {Platform} Virtual Scroll has no dependencies on other components and needs + + +The {Platform} Virtual Scroll has no dependencies on other components and needs no theme of its own. `igniteui-react` brings in `igniteui-webcomponents` and `lit`, and the components in the item template need a theme stylesheet. + + + ## Additional Resources - [{ProductName} **Forums**]({ForumsLink}) @@ -674,14 +998,16 @@ The {Platform} Virtual Scroll has no dependencies on other components and needs - [List](../list.mdx) - Use the List for a short list, or as the container of a virtualized list. +- [Data Grid](../grid/grid.mdx) - Use the Data Grid for tabular data with columns, sorting, or filtering. - [Card](../card.mdx) - Use cards for a small set of rich items, or as items of a horizontal Virtual Scroll. - [Virtual ForOf Directive](../for-of.mdx) - The directive-based virtualization used by existing lists. - + - [List](../grids/list.mdx) - Use the List for a short list, or as the container of a virtualized list. +- [Data Grid](../grids/data-grid.mdx) - Use the Data Grid for tabular data with columns, sorting, or filtering. - [Card](./card.mdx) - Use cards for a small set of rich items, or as items of a horizontal Virtual Scroll. @@ -694,6 +1020,9 @@ The {Platform} Virtual Scroll has no dependencies on other components and needs Items in the {Platform} Virtual Scroll can have different sizes, because each item is measured once it renders. Set `estimatedItemSize` close to the average item size so that the scrollbar is accurate before items are measured. + + Once items are measured, their average replaces the estimate for the items that are not measured yet. + Call the {Platform} Virtual Scroll `scrollToIndex` method with the item index and optional `block` and `behavior` options. The method returns a promise that resolves when the corrected position is stable. @@ -705,5 +1034,9 @@ The {Platform} Virtual Scroll has no dependencies on other components and needs The {Platform} Virtual Scroll supports append-only loading through the `igcDataRequest` event. Handle the event and assign a new array that includes the requested items to `data`. + + + The {Platform} Virtual Scroll supports append-only loading through the `onDataRequest` event. Handle the event and assign a new array that includes the requested items to `data`. + diff --git a/docs/xplat/src/content/en/toc.json b/docs/xplat/src/content/en/toc.json index e9bbfcbd2f..ef0a95b26c 100644 --- a/docs/xplat/src/content/en/toc.json +++ b/docs/xplat/src/content/en/toc.json @@ -2603,7 +2603,6 @@ }, { "exclude": [ - "React", "Blazor" ], "name": "Virtual Scroll", diff --git a/docs/xplat/src/content/jp/components/layouts/virtual-scroll.mdx b/docs/xplat/src/content/jp/components/layouts/virtual-scroll.mdx index b5dbdd5708..06c76a3cca 100644 --- a/docs/xplat/src/content/jp/components/layouts/virtual-scroll.mdx +++ b/docs/xplat/src/content/jp/components/layouts/virtual-scroll.mdx @@ -1,25 +1,29 @@ --- title: "Virtual Scroll" description: "Virtual Scroll は、ビューポート内のアイテムと少量のバッファーのみをレンダリングするコンポーネントであり、大量のリストでもスムーズにスクロールできます。" -keywords: "{Platform} Virtual Scroll, virtualization, virtual list, large lists, infinite scroll, remote data, {ProductName}" -last_updated: "2026-09-17" +keywords: "{Platform} Virtual Scroll, virtualization, virtual list, large lists, infinite scroll, remote data, {ProductName}, 仮想スクロール, 仮想化, 仮想リスト, 大量リスト, 無限スクロール, リモート データ" +last_updated: "2026-09-25" license: MIT mentionedTypes: ["VirtualScroll"] -relatedComponents: ["List", "Card"] +relatedComponents: ["List", "Grid", "Card"] _language: ja llms: description: "{ProductName} Virtual Scroll は、ビューポート内のアイテムと設定可能なバッファーのみを DOM 内に保持することで、大量のリストをレンダリングするコンポーネントです。" --- -import DocsAside from 'igniteui-astro-components/components/mdx/DocsAside.astro'; import PlatformBlock from 'igniteui-astro-components/components/mdx/PlatformBlock.astro'; import Sample from 'igniteui-astro-components/components/mdx/Sample.astro'; import ApiLink from 'igniteui-astro-components/components/mdx/ApiLink.astro'; +import Anatomy from 'igniteui-astro-components/components/mdx/Anatomy.astro'; import Faq from 'igniteui-astro-components/components/mdx/Faq.astro'; import FaqItem from 'igniteui-astro-components/components/mdx/FaqItem.astro'; +import { Image } from 'astro:assets'; +import virtualScrollAnatomy from '@xplat-images/anatomy-content-light/virtual-scroll-lt-a.png'; +import virtualScrollDo from '@xplat-images/virtual-scroll/virtual-scroll-do.png'; +import virtualScrollDoNot from '@xplat-images/virtual-scroll/virtual-scroll-do-not.png'; # Virtual Scroll コンポーネント -{ProductName} Virtual Scroll は、ビューポート内のアイテムと設定可能なバッファーのみを DOM 内に保持することで、大量のリストをレンダリングするコンポーネントです。スクロールバーはコレクション全体に及ぶため、10 万件のアイテムを持つ仮想リストでも通常のリストと同じようにスクロールできます。 +{ProductName} Virtual Scroll は、ビューポート内のアイテムと設定可能なバッファーのみを DOM 内に保持することで、大量のリストをレンダリングするコンポーネントです。スクロールバーは常にコレクション全体の範囲を表すため、10 万件のアイテムを持つ仮想リストでも通常のリストと同じようにスクロールできます。 ## ライブ デモ @@ -29,7 +33,7 @@ import FaqItem from 'igniteui-astro-components/components/mdx/FaqItem.astro'; - + @@ -39,7 +43,27 @@ import FaqItem from 'igniteui-astro-components/components/mdx/FaqItem.astro'; {Platform} Virtual Scroll は、表示されているアイテムと設定可能なバッファーをレンダリングし、そのトラックはコレクション全体のスクロール範囲を保持します。 -{/*TODO: add the Virtual Scroll anatomy image and render it with the component.*/} + + + + +1. ホスト: スクロール コンテナーです。固定の高さ (水平の場合は幅) によって、表示されるアイテムの数が決まります。
+2. トラック: コレクション全体の推定される長さに合わせてサイズが設定されるスペーサーです。これにより、スクロールバーがすべてのアイテムに及びます。
+3. コンテンツ要素: レンダリングされたアイテムのみを保持します。ビューポートの上にある、最初にレンダリングされたバッファー アイテムから始まり、そのサイズはレンダリングされたアイテムによって決まります。
+4. アイテム ラッパー: レンダリングされたアイテムごとに 1 つ存在し、アイテム テンプレートをホストします。サイズが測定されるのはこのボックスです。
+5. オーバー スキャン バッファー: ビューポートの各端を超えてレンダリングされる overScan 個のアイテム (デフォルトは 2) です。
@@ -52,7 +76,7 @@ igx-virtual-scroll — scrollable viewport (role="list") - + ```text igc-virtual-scroll — scrollable viewport @@ -116,7 +140,32 @@ virtualScroll.data = Array.from({ length: 100_000 }, (_, i) => ({ name: `Item ${ -Virtual Scroll のホストには、垂直スクロールの場合は固定の高さ、水平スクロールの場合は固定の幅が必要です。コンテンツに合わせてサイズが拡大するホストには、埋めるべきビューポートがありません。 + + +[作業の開始](../general-getting-started.mdx) のトピックに従って {ProductName} をセットアップし、 をインポートして、アイテム テンプレートとデータを指定します。React ラッパーはモジュールの読み込み時に基になる要素を登録するため、登録の呼び出しは不要です。 + +```tsx +import { IgrVirtualScroll } from 'igniteui-react'; +import type { VirtualScrollItemContext } from 'igniteui-react'; + +const items = Array.from({ length: 100_000 }, (_, i) => ({ name: `Item ${i}` })); + +export function Employees() { + return ( + ) => ( +
{ctx.index}: {ctx.value.name}
+ )} + style={{ height: '400px' }} + /> + ); +} +``` + +
+ +Virtual Scroll のホストには、垂直スクロールの場合は固定の高さ、水平スクロールの場合は固定の幅が必要です。コンテンツに合わせてサイズが拡大するホストはすべてのアイテムをレンダリングするため、リストは仮想化されません。 ### 前提条件とバージョン互換性 @@ -140,19 +189,31 @@ Virtual Scroll のホストには、垂直スクロールの場合は固定の
+ + +| 要件 | 値 | +| --- | --- | +| パッケージ | `igniteui-react` (MIT) | +| コンポーネントが最初にリリースされたバージョン | 19.9.0 | +| ピア パッケージ | `react` および `react-dom` 18 または 19 | +| アイテム テンプレート | 関数から返される JSX。`igniteui-webcomponents` は `igniteui-react` の依存関係として含まれるため、個別にインストールする必要はありません。 | +| テーマ | テーマ スタイルシートを 1 度インポートします。例: `igniteui-webcomponents/themes/light/bootstrap.css`。 | + + + ## 使用方法 ### アイテム テンプレート -Virtual Scroll のアイテム テンプレートは、アイテムとコレクション全体におけるその位置を受け取ります。位置に依存するコンテンツ(交互のスタイルや `aria-posinset`、`aria-setsize` など)には、インデックスと合計件数を使用します。 +Virtual Scroll のアイテム テンプレートは、アイテムとコレクション全体におけるその位置を受け取ります。位置に依存するコンテンツ (交互のスタイルや `aria-posinset`、`aria-setsize` など) には、インデックスと合計件数を使用します。 -`ng-template` に `igxVirtualItem` を付与するか、 を通じて他の場所で定義されたテンプレートを渡します(こちらが優先されます)。テンプレートのコンテキストは `$implicit`(アイテム)、`index`、`count`、`first`、`last`、`even`、`odd` を提供します。 +`ng-template` に `igxVirtualItem` を付与するか、 を通じて他の場所で定義されたテンプレートを渡します (こちらが優先されます)。テンプレートのコンテキストは `$implicit` (アイテム)、`index`、`count`、`first`、`last`、`even`、`odd` を提供します。 ```html - + @@ -168,7 +229,7 @@ Virtual Scroll のアイテム テンプレートは、アイテムとコレク - に、Lit テンプレートを返す関数を設定します。この関数は、`value`(アイテム)、`index`、`count`、`isFirst`、`isLast` を持つ `VirtualScrollItemContext` を受け取ります。アイテム テンプレートがない場合、コンポーネントは何もレンダリングしません。 + に、Lit テンプレートを返す関数を設定します。この関数は、`value` (アイテム)、`index`、`count`、`isFirst`、`isLast` を持つ `VirtualScrollItemContext` を受け取ります。アイテム テンプレートがない場合、コンポーネントは何もレンダリングしません。 ```ts virtualScroll.itemTemplate = (ctx: VirtualScrollItemContext) => html` @@ -182,6 +243,27 @@ virtualScroll.itemTemplate = (ctx: VirtualScrollItemContext) => html` + + + に、JSX を返す関数を設定します。この関数は、`value` (アイテム)、`index`、`count`、`isFirst`、`isLast` を持つ `VirtualScrollItemContext` を受け取ります。アイテム テンプレートがない場合、コンポーネントは何もレンダリングしません。 + +```tsx +) => ( + + + {ctx.value.name} + {ctx.value.email} + + )} + style={{ height: '480px' }} +/> +``` + + + ### データ Virtual Scroll の コレクションは参照によって比較されます。リストを更新するには新しい配列を割り当てる必要があります。`push` などでバインドされた配列をその場で変更しても更新されません。 @@ -202,11 +284,41 @@ virtualScroll.data = [...virtualScroll.data, newEmployee]; -`data` が変更されると、コンポーネントは最初に変更されたインデックスより前のアイテムの測定済みサイズを保持し、それ以降のアイテムはレンダリング時に再度測定します。追加操作ではすべての既存の測定値が保持されますが、置換、フィルタリング、並べ替えでは最初に変更されたアイテム以降の測定値が破棄されます。 + + +```tsx +setEmployees(current => [...current, newEmployee]); +``` + + + +`data` が変更されると、コンポーネントは最初に変更されたインデックスより前のアイテムの測定済みサイズを保持し、それ以降のアイテムはレンダリング時に再度測定します。追加操作ではすべての既存の測定値が保持されますが、置換、フィルタリング、ソートでは最初に変更されたアイテム以降の測定値が破棄されます。 + + + +アイテムは、そのキーがレンダリングされたウィンドウ内にある間、同じ要素を保持します。 を指定しない場合はインデックスがキーになるため、ソート、挿入、削除の後もそのインデックスの要素はそのまま残り、新しいアイテムを表示します。アイテムが `data` 内で移動する場合は、`keyFunction` から安定した ID を返してください。 + +```ts +virtualScroll.keyFunction = (employee) => employee.id; +``` + + ### 推定アイテム サイズ -Virtual Scroll の は、アイテムがレンダリングされて測定されるまでのピクセル単位のサイズです(デフォルトは `50`)。アイテムは異なるサイズを持つことができ、測定されたサイズがそれぞれ推定値を置き換えます。アイテムが測定される前にスクロールバーと `scrollToIndex` を正確に保つため、推定値はアイテムの平均サイズに近い値に設定してください。 +Virtual Scroll の は、アイテムがレンダリングされて測定されるまでのピクセル単位のサイズです (デフォルトは `50`)。アイテムは異なるサイズを持つことができ、測定されたサイズがそれぞれ推定値を置き換えます。 + + + +アイテムが測定される前にスクロールバーと `scrollToIndex` を正確に保つため、推定値はアイテムの平均サイズに近い値に設定してください。 + + + + + +最初のレンダリングが実際の内容に近くなるよう、推定値はアイテムの平均サイズに近い値に設定してください。アイテムが測定されると、まだ測定されていないアイテムの推定値は測定済みの平均サイズに置き換えられるため、推定値がずれていてもスクロールバーと `scrollToIndex` は自動的に補正されます。 + + @@ -228,11 +340,21 @@ Virtual Scroll の + + +```tsx + +``` + + + + + アイテムはボーダー ボックスで測定されるため、マージンはアイテムのサイズに含まれません。マージンの代わりに、パディング、またはアイテム内の `gap` を使用してアイテム間の間隔を設定してください。 ### 方向 -Virtual Scroll の は、スクロール軸を `vertical`(デフォルト)または `horizontal` に設定します。水平リストでは、各アイテムに幅を、ホストに高さを設定してください。右から左のコンテキストでは、水平スクロールとアイテムの配置が反転します。 +Virtual Scroll の は、スクロール軸を `vertical` (デフォルト) または `horizontal` に設定します。水平リストでは、各アイテムに幅を、ホストに高さを設定してください。右から左のコンテキストでは、水平スクロールとアイテムの配置が反転します。 @@ -258,9 +380,25 @@ Virtual Scroll の + +```tsx +
...
} + style={{ height: '200px' }} +/> +``` + + + +
+ ### オーバー スキャン -Virtual Scroll の は、ビューポートの各端を超えてレンダリングされる追加アイテムの数です(デフォルトは `2`)。値を大きくすると、高速スクロール中の空白領域が減りますが、レンダリングする要素が増えます。 +Virtual Scroll の は、ビューポートの各端を超えてレンダリングされる追加アイテムの数です (デフォルトは `2`)。値を大きくすると、高速スクロール中の空白領域が減りますが、レンダリングする要素が増えます。 @@ -278,9 +416,17 @@ Virtual Scroll の + +```tsx + +``` + + + ### インデックスへのスクロール -Virtual Scroll の メソッドは、アイテムが表示される位置までスクロールします。オプションはネイティブの `scrollIntoView` と同じで、`block`(`start`、`center`、`end`、または `nearest`)、水平リスト用の `inline`、`behavior`(`auto` または `smooth`)を指定できます。まだレンダリングされていないアイテムには推定サイズしかないため、コンポーネントは到達した位置のアイテムを測定して位置を補正します。返されるプロミスは最終的な位置が確定すると解決されます。 +Virtual Scroll の メソッドは、アイテムが表示される位置までスクロールします。オプションはネイティブの `scrollIntoView` と同じで、`block` (`start`、`center`、`end`、または `nearest`)、水平リスト用の `inline`、`behavior` (`auto` または `smooth`) を指定できます。まだレンダリングされていないアイテムには推定サイズしかないため、コンポーネントは到達した位置のアイテムを測定して位置を補正します。返されるプロミスは最終的な位置が確定すると解決されます。 @@ -306,13 +452,27 @@ await virtualScroll.scrollToIndex(index, { block: 'center' }); -`block: 'nearest'` を指定した場合、アイテムがすでに完全に表示されているときは位置が変更されません。コレクションの範囲外のインデックスは、最初または最後のアイテムにクランプされます。 + + +```tsx +const virtualScroll = useRef(null); + +async function goTo(index: number): Promise { + await virtualScroll.current?.scrollToIndex(index, { block: 'center' }); +} +``` + + + + + +`block: 'nearest'` を指定した場合、アイテムがすでに完全に表示されているときは位置が変更されません。コレクションの範囲外のインデックスは、最初または最後のアイテムに丸められます。 ### 無限スクロール -Virtual Scroll の 出力は、リモート データからの追加専用の読み込みをサポートします。これは、レンダリングされたウィンドウが `data` の末尾に近づいたときや、読み込まれたアイテムが最初のレンダリングでビューポートを満たさない場合に発行されます。要求されたアイテムを新しい配列として追加します。 +Virtual Scroll の 出力は、リモート データからの追加専用の読み込みをサポートします。これは、レンダリングされたウィンドウが `data` の末尾に近づいたときや、読み込まれたアイテムが最初のレンダリングでビューポートを満たさない場合に発生します。要求されたアイテムを新しい配列として追加します。 ```html @@ -336,7 +496,7 @@ public loadMore(request: VirtualScrollDataRequest): void { -Virtual Scroll の `igcDataRequest` イベントは、リモート データからの追加専用の読み込みをサポートします。これは、レンダリングされたウィンドウが `data` の末尾に近づいたときや、読み込まれたアイテムが最初のレンダリングでビューポートを満たさない場合に発行されます。要求されたアイテムを新しい配列として追加します。 +Virtual Scroll の `igcDataRequest` イベントは、リモート データからの追加専用の読み込みをサポートします。これは、レンダリングされたウィンドウが `data` の末尾に近づいたときや、読み込まれたアイテムが最初のレンダリングでビューポートを満たさない場合に発生します。要求されたアイテムを新しい配列として追加します。 ```ts virtualScroll.addEventListener('igcDataRequest', (event: CustomEvent) => { @@ -351,13 +511,34 @@ virtualScroll.addEventListener('igcDataRequest', (event: CustomEvent -一度に保留できるデータ要求は 1 つだけで、次の要求は `data` が次に変更された後に発行されます。`data` が空の場合は要求が発行されないため、最初のページは自分で読み込む必要があります。ソースにこれ以上アイテムがない場合は追加を停止してください。コンポーネントは同じ開始インデックスを再度要求することはありません。 + + +Virtual Scroll の `onDataRequest` イベントは、リモート データからの追加のみの読み込みをサポートします。レンダリングされたウィンドウが `data` の末尾に近づいたとき、および読み込み済みのアイテムがビューポートを埋めない場合は最初のレンダリング時に発生します。要求されたアイテムを新しい配列として追加します。 + +```tsx +) => { + const { startIndex, count } = event.detail; + const page = await fetchEmployees(startIndex, count); + setEmployees(current => [...current, ...page]); + }} + style={{ height: '440px' }} +/> +``` + + + + + +一度に保留できるデータ要求は 1 つだけで、次の要求は `data` が次に変更された後に発行されます。`data` が空の場合は要求が発行されないため、最初のページは自分で読み込む必要があります。ソースにこれ以上アイテムがない場合は、追加を停止するだけでかまいません。コンポーネントが同じ開始インデックスを再度要求することはありません。 ### ページ分割されたデータ -Angular Virtual Scroll の 入力は、`data` の代わりに大きなコレクションの 1 ページをバインドします。リストは `totalCount` と同じ長さになるため、ページのみがメモリ上にある間もスクロールバーはコレクション全体に及び、ページがカバーしていないインデックスは何もレンダリングしません。 +Angular Virtual Scroll の 入力は、`data` の代わりに大きなコレクションの 1 ページをバインドします。リストは `totalCount` と同じ長さになるため、ページのみがメモリ上にある間もスクロールバーはコレクション全体の範囲を表し、ページがカバーしていないインデックスは何もレンダリングしません。 ```ts interface VirtualDataWindow { @@ -397,7 +578,7 @@ public onStateChange(state: VirtualScrollState): void { -`totalCount` が変わらない間は、インデックスごとに測定済みサイズが保持されます。フィルタリング結果のように `totalCount` が異なるページは再度測定されます。`dataWindow` がバインドされている間は `dataRequest` は発行されません。コンポーネントはインデックスごとに 1 つのサイズ エントリを保存するため、そのメモリは `totalCount` に応じて増加します。100 万件のアイテムでおおよそ 17 MB です。 +`totalCount` が変わらない間は、インデックスごとに測定済みサイズが保持されます。フィルタリング結果のように `totalCount` が異なるページは再度測定されます。`dataWindow` がバインドされている間は `dataRequest` は発生しません。コンポーネントはインデックスごとに 1 つのサイズ エントリを保存するため、そのメモリは `totalCount` に応じて増加します。100 万件のアイテムでおおよそ 17 MB です。 @@ -423,32 +604,130 @@ await virtualScroll.layoutComplete; + + +```tsx +setEmployees(await fetchEmployees()); +await virtualScroll.current?.layoutComplete; +``` + + + ### 使用すべき場合と使用すべきでない場合 -{/*TODO: add the Virtual Scroll Do/Don't guidance image from Indigo.Design when it is available.*/} +Virtual Scroll は通常、長いリストのスクロール コンテナーとして機能し、ビューポート内のアイテムと小さなバッファーのみを DOM に保持します。一度にレンダリングできる短いリストには使用しないでください。また、アイテム テンプレートを作成する際は、各アイテムの状態を要素ではなくデータに保持してください。アイテムの要素は再利用されるため、テンプレートがバインドしていない DOM の状態は、その要素を受け取ったアイテムに表示されます。 + + + +
+
+
+{Platform} Virtual Scroll showing a list of 100,000 employees +
+
+使用すべき + +ディレクトリ、フィード、ログ、横一列に並んだカードなど、一度にレンダリングするには大きすぎる長いリストに対して Virtual Scroll を使用します。これには、スクロール中にリモート データを読み込むリストも含まれます。 + +
+
+
+
+{Platform} Virtual Scroll used for a list of only five employees +
+
+使用すべきでない -**使用すべき場合:** ディレクトリ、フィード、ログ、カードのストリップなど、一度にレンダリングするには大きすぎる長いリストに対して Virtual Scroll を使用します。これには、スクロール中にリモート データを読み込むリストも含まれます。 - -**使用すべきでない場合:** 短いリストは [List](../list.mdx) と `@for` で直接レンダリングします。列、並べ替え、フィルタリングを伴う表形式のデータには [Grid](../grid/grid.mdx) を使用します。仮想化を行わずにリッチなアイテムの少量のセットを表示するには [Card](../card.mdx) を使用します。 +短いリストは [List](../list.mdx) と `@for` で直接レンダリングします。列、ソート、フィルタリングを伴う表形式のデータには [{Platform} Data Grid](../grid/grid.mdx) を使用します。仮想化せずに少数のリッチなアイテムを表示するには [Card](../card.mdx) を使用します。 - - -**使用すべき場合:** ディレクトリ、フィード、ログ、カードのストリップなど、一度にレンダリングするには大きすぎる長いリストに対して Virtual Scroll を使用します。これには、スクロール中にリモート データを読み込むリストも含まれます。 + -**使用すべきでない場合:** 短いリストは [List](../grids/list.mdx) で直接レンダリングします。仮想化を行わずにリッチなアイテムの少量のセットを表示するには [Card](./card.mdx) を使用します。 +短いリストは [List](../grids/list.mdx) で直接レンダリングします。列、ソート、フィルタリングを伴う表形式のデータには [{Platform} Data Grid](../grids/data-grid.mdx) を使用します。仮想化せずに少数のリッチなアイテムを表示するには [Card](./card.mdx) を使用します。 -| 推奨 | 非推奨 | -| --- | --- | -| ホストに固定の高さ(垂直)または幅(水平)を指定する。 | ホストのサイズをコンテンツに合わせて拡大させる。 | -| `estimatedItemSize` をアイテムの平均サイズに近い値に設定する。 | はるかに大きい、または小さいアイテムに対してデフォルトの 50px を維持する。 | -| コレクションが変更されたときに新しい配列を割り当てる。 | バインドされた配列をその場で変更する。 | -| パディングまたは `gap` でアイテム間の間隔を設定する。 | マージンでアイテム間の間隔を設定する。 | +
+
+
## プロパティ @@ -462,7 +741,7 @@ await virtualScroll.layoutComplete; | | `number` | `2` | ビューポートの各端を超えてレンダリングされる追加アイテムの数。 | | | `number` | `50` | アイテムが測定されるまでのピクセル単位のサイズ。0 以下の値の場合は `50` が使用されます。 | | | `TemplateRef> \| null` | `null` | アイテム テンプレート。投影された `ng-template[igxVirtualItem]` より優先されます。 | -| | `Promise`(読み取り専用) | — | レンダリングとアイテムの測定が落ち着くと解決されます。 | +| | `Promise` (読み取り専用) | — | レンダリングとアイテムの測定が完了すると解決されます。 |
@@ -475,7 +754,22 @@ await virtualScroll.layoutComplete; | | `number` | `2` | ビューポートの各端を超えてレンダリングされる追加アイテムの数。属性: `over-scan`。 | | | `number` | `50` | アイテムが測定されるまでのピクセル単位のサイズ。0 以下の値の場合は `50` が使用されます。属性: `estimated-item-size`。 | | | `VirtualScrollItemTemplate \| null` | `null` | 各アイテムをレンダリングする関数。プロパティのみ。 | -| | `Promise`(読み取り専用) | — | レンダリングとアイテムの測定が落ち着くと解決されます。 | +| | `VirtualScrollKeyFunction \| null` | `null` | アイテムのキーを返します。これにより、アイテムが `data` 内で移動しても同じ要素が保持されます。指定しない場合はインデックスがキーになります。プロパティのみ。 | +| | `Promise` (読み取り専用) | — | レンダリングとアイテムの測定が完了すると解決されます。 | + +
+ + + +| 名前 | 型 | デフォルト | 説明 | +| --- | --- | --- | --- | +| | `any[]` | `[]` | 仮想化するコレクション。参照で比較されます。 | +| | `'vertical' \| 'horizontal'` | `'vertical'` | スクロール軸。 | +| | `number` | `2` | ビューポートの各端を超えてレンダリングされる追加のアイテム数。 | +| | `number` | `50` | 測定されるまでのアイテムのサイズ (ピクセル)。0 以下の値は `50` として扱われます。 | +| | `(ctx: VirtualScrollItemContext) => ReactNode` | `null` | 各アイテムをレンダリングする関数。 | +| | `(item, index) => unknown` | `null` | アイテムのキーを返します。これにより、アイテムが `data` 内で移動しても同じ要素が保持されます。指定しない場合はインデックスがキーになります。 | +| | `Promise` (読み取り専用) | — | レンダリングとアイテムの測定が完了すると解決します。プロパティとしてではなく、ref から読み取ります。 | @@ -483,7 +777,7 @@ await virtualScroll.layoutComplete; | 名前 | 戻り値 | 説明 | | --- | --- | --- | -| | `Promise` | `index` のアイテムをビューにスクロールし、最終的なスクロール位置が確定すると完了します。 | +| | `Promise` | `index` のアイテムをビューにスクロールし、最終的なスクロール位置が確定すると解決されます。 | ## イベント @@ -491,8 +785,8 @@ await virtualScroll.layoutComplete; | 名前 | ペイロード | 説明 | | --- | --- | --- | -| | `VirtualScrollState` | レンダリングされたウィンドウが変更されたときに発行されます: `startIndex`、`endIndex`、`viewportSize`、`totalSize`。 | -| | `VirtualScrollDataRequest` | レンダリングされたウィンドウが `data` の末尾に近づいたときに発行されます: `startIndex`、`count`。`dataWindow` がバインドされている間は発行されません。 | +| | `VirtualScrollState` | レンダリングされたウィンドウが変更されたときに発生します: `startIndex`、`endIndex`、`viewportSize`、`totalSize`。 | +| | `VirtualScrollDataRequest` | レンダリングされたウィンドウが `data` の末尾に近づいたときに発生します: `startIndex`、`count`。`dataWindow` がバインドされている間は発生しません。 |
@@ -500,8 +794,19 @@ await virtualScroll.layoutComplete; | 名前 | 詳細 | 説明 | | --- | --- | --- | -| `igcStateChange` | `VirtualScrollState` | レンダリングされたウィンドウが変更されたときに発行されます: `startIndex`、`endIndex`、`viewportSize`、`totalSize`。 | -| `igcDataRequest` | `VirtualScrollDataRequest` | レンダリングされたウィンドウが `data` の末尾に近づいたときに発行されます: `startIndex`、`count`。 | +| `igcStateChange` | `VirtualScrollState` | レンダリングされたウィンドウが変更されたときに発生します: `startIndex`、`endIndex`、`viewportSize`、`totalSize`。 | +| `igcDataRequest` | `VirtualScrollDataRequest` | レンダリングされたウィンドウが `data` の末尾に近づいたときに発生します: `startIndex`、`count`。 | + +
+ + + +| 名前 | 引数 | 説明 | +| --- | --- | --- | +| `onStateChange` | `CustomEvent` | レンダリングされたウィンドウが変更されたときに発生します。`event.detail` は `startIndex`、`endIndex`、`viewportSize`、`totalSize` を持ちます。 | +| `onDataRequest` | `CustomEvent` | レンダリングされたウィンドウが `data` の末尾に近づいたときに発生します。`event.detail` は `startIndex` と `count` を持ちます。 | + +ハンドラーはネイティブの `CustomEvent` を受け取るため、ペイロードは `event.detail` から読み取ります。 @@ -525,7 +830,7 @@ await virtualScroll.layoutComplete;
- + コンポーネントはライト DOM 内にレンダリングされるため、通常のセレクターでレンダリングされたアイテムに到達できます。デフォルトのスタイルはホストに `18.75rem` の高さを与えます。ビューポートのサイズを変更するには、この高さを上書きしてください。 @@ -547,7 +852,7 @@ igc-virtual-scroll.employees [data-vs-index]:nth-child(even) { ### キーボード インタラクション -{Platform} Virtual Scroll はキー ハンドラーを追加しません。ホストはネイティブのスクロール コンテナーであり、フォーカスされたスクロール コンテナーはブラウザーのキーでスクロールします。 +{Platform} Virtual Scroll はキー ハンドラーを追加しません。ホストはネイティブのスクロール コンテナーであり、フォーカスされたスクロール コンテナーはブラウザー標準のキー操作でスクロールします。 | キー | アクション | | --- | --- | @@ -556,19 +861,20 @@ igc-virtual-scroll.employees [data-vs-index]:nth-child(even) { | Page Up / Page Down | ビューポート 1 つ分ほどスクロールします。 | | Home / End | コレクションの先頭または末尾にスクロールします。 | -ホストには `tabindex` がありません。フォーカス可能なコンテンツがないスクロール コンテナーがフォーカスを受け取れるかどうかはブラウザーによって異なるため、アイテムにフォーカス可能な要素が含まれない場合は、ホストに `tabindex="0"` を設定してください。ビューから外れてスクロールされたアイテムは DOM から削除されるため、削除されたアイテム内のフォーカスは失われます。 +ホストには `tabindex` がありません。フォーカス可能なコンテンツがないスクロール コンテナーがフォーカスを受け取れるかどうかはブラウザーによって異なるため、アイテムにフォーカス可能な要素が含まれない場合は、ホストに `tabindex="0"` を設定してください。アイテム内のフォーカスは、そのアイテムがレンダリングされたウィンドウから外れると保持されません。外れる前に意図的にフォーカスを移動してください。 ### スクリーン リーダー / ARIA - ホストには `role="list"` が設定されています。トラック、コンテンツ要素、アイテム ラッパーには `role="presentation"` が設定されています。`igx-list-item` のように `role="listitem"` をレンダリングするアイテムは、そのリストのアイテムとして公開されます。 +- `igx-list` のように既にリストのセマンティクスを提供するコンテナー内では、アイテムが二重のリストに入れ子にならないよう、ホストに `role="presentation"` を設定してください。 - `index` と `count` のテンプレート変数を `aria-posinset` と `aria-setsize` にマップします。 - フォーカス可能なホストには、`aria-label` または `aria-labelledby` でアクセシブルな名前を付けてください。 - + - トラック、コンテンツ要素、アイテム ラッパーには `role="presentation"` が設定されています。ホストにはロールがありません。`igc-list` のようにリストのロールを持つ要素の中に配置するか、アイテムが `role="listitem"` をレンダリングする場合はホストに `role="list"` を設定してください。 - `index` と `count` のコンテキスト プロパティを `aria-posinset` と `aria-setsize` にマップします。 @@ -578,25 +884,25 @@ igc-virtual-scroll.employees [data-vs-index]:nth-child(even) { ### アクセシビリティ準拠 -Infragistics は、{ProductName} が対象とするアクセシビリティ標準を [アクセシビリティ準拠](../interactivity/accessibility-compliance.mdx) トピックで文書化しています。このトピックは Virtual Scroll に対する準拠の主張を行うものではありません。表にはコンポーネントが提供する内容が記載されており、その後のリストにはアプリケーションが追加する必要がある内容が記載されています。 +インフラジスティックスは、{ProductName} が対象とするアクセシビリティ標準を [アクセシビリティ準拠](../interactivity/accessibility-compliance.mdx) トピックで文書化しています。このトピックは Virtual Scroll に対する準拠の主張を行うものではありません。表にはコンポーネントが提供する内容が記載されており、その後のリストにはアプリケーションが追加する必要がある内容が記載されています。 | 基準 | コンポーネントが要件をサポートする方法 | | --- | --- | -| [1.3.1 情報及び関係性](https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships) | ラッパーは表示専用であるため、リスト構造はホストとアイテム テンプレートから提供され、`aria-posinset` と `aria-setsize` で各アイテムの位置を公開できます。 | +| [1.3.1 情報及び関係性](https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships) | ラッパーには `role="presentation"` が設定されているため、リスト構造はホストとアイテム テンプレートから提供され、`aria-posinset` と `aria-setsize` で各アイテムの位置を公開できます。 | | [2.1.1 キーボード](https://www.w3.org/WAI/WCAG21/Understanding/keyboard) | ホストはネイティブのスクロール コンテナーであり、フォーカスを得るとキーボードでスクロールできます。キーボードでホストに到達できるかどうかはアプリケーションに依存します。以下のリストを参照してください。 | ユーザー側の責任: - アイテムにフォーカス可能な要素が含まれない場合は、`tabindex="0"` を設定してホストをキーボードで到達可能にし、アクセシブルな名前を付けてください。 - アイテム テンプレートから `aria-posinset` と `aria-setsize` でアイテムの位置を公開してください。 -- アイテム テンプレートに適したリスト セマンティクスを提供してください([スクリーン リーダー / ARIA](#スクリーン-リーダー--aria) を参照)。 +- アイテム テンプレートに適したリスト セマンティクスを提供してください ([スクリーン リーダー / ARIA](#スクリーン-リーダー--aria) を参照)。 - 選択などのアプリケーションの状態は、レンダリングされたアイテム要素ではなくデータ内に保持してください。 ## トラブルシューティング ### Virtual Scroll がアイテムをレンダリングしないのはなぜですか? -ホストにスクロール軸方向のサイズがない、アイテム テンプレートがない、または `data` が空です。ホストに固定の高さ(垂直)または幅(水平)を設定し、アイテム テンプレートを設定して、バインドされたコレクションを確認してください。 +ホストにスクロール軸方向のサイズがない、アイテム テンプレートがない、または `data` が空です。ホストに固定の高さ (垂直) または幅 (水平) を設定し、アイテム テンプレートを設定して、バインドされたコレクションを確認してください。 ### アイテムを追加してもリストが更新されないのはなぜですか? @@ -604,7 +910,19 @@ Virtual Scroll は `data` を参照によって比較するため、その場で ### スクロール中にスクロールバーのサイズが変わるのはなぜですか? -まだレンダリングされていないアイテムは `estimatedItemSize` を使用しており、アイテムが測定されるにつれて合計サイズが補正されます。`estimatedItemSize` をアイテムの平均サイズに近い値に設定してください。 +まだレンダリングされていないアイテムは `estimatedItemSize` を使用しており、アイテムが測定されるにつれて合計サイズが補正されます。 + + + +`estimatedItemSize` をアイテムの平均サイズに近い値に設定してください。 + + + + + +その後、まだ測定されていないアイテムの推定値は測定済みの平均サイズに置き換えられるため、スクロールするにつれて補正が収束します。最初のレンダリングが実際の内容に近くなるよう、`estimatedItemSize` はアイテムの平均サイズに近い値に設定してください。 + + ### リストの下の方でアイテムの位置がずれるのはなぜですか? @@ -625,21 +943,21 @@ Virtual Scroll は実行時にアイテムを測定し、独自のスクロー | `*igxFor="let item of data"` | `ng-template igxVirtualItem` を伴う `[data]="data"` | | `igxForScrollOrientation` | `orientation` | | `igxForContainerSize` | CSS で設定するホストの高さまたは幅 | -| `igxForItemSize` | `estimatedItemSize`(開始時の推定値。アイテムは測定されます) | +| `igxForItemSize` | `estimatedItemSize` (開始時の推定値。アイテムは測定されます) | | `igxForScrollContainer` | 不要: ホストがスクロール コンテナーです | | `scrollTo(index)` | プロミスを返す `scrollToIndex(index, options)` | | `chunkLoad`、`chunkPreload` | `stateChange` | -| `totalItemCount` を伴う `igxForRemote` | `totalCount` を伴う `dataWindow`、または追加専用の読み込み向けに `dataRequest` を伴う `data` | +| リモート データ向けの `igxForTotalItemCount` | `totalCount` を伴う `dataWindow`、または追加専用の読み込み向けに `dataRequest` を伴う `data` | | `index`、`count`、`first`、`last`、`even`、`odd` | 同じテンプレート変数 | -グリッドは独自の行と列の仮想化を維持します。[グリッドの仮想化](../grid/virtualization.mdx) を参照してください。 +グリッドには独自の行と列の仮想化機能があります。[グリッドの仮想化](../grid/virtualization.mdx) を参照してください。 ## 既知の制限 - {Platform} Virtual Scroll は単一の軸を仮想化します。行と列の両方を仮想化するにはグリッドが必要です。 -- ビューから外れてスクロールされたアイテムは、フォーカスと内部状態とともに DOM から削除されます。 +- ウィンドウの移動に伴ってアイテムの要素は再利用されるため、`checked` をバインドしていないチェックボックスなど、アイテム テンプレートがバインドしていない DOM の状態は、その要素を受け取ったアイテムに表示されます。アイテムの状態はすべてバインドし、ユーザーによる変更はアイテムに書き戻してください。 @@ -665,6 +983,12 @@ Angular Virtual Scroll は、他のコンポーネントへの依存関係を持 + + +{Platform} Virtual Scroll は他のコンポーネントへの依存関係を持たず、独自のテーマも必要としません。`igniteui-react` が `igniteui-webcomponents` と `lit` を含み、アイテム テンプレート内のコンポーネントにはテーマ スタイルシートが必要です。 + + + ## その他のリソース - [{ProductName} **フォーラム (英語)**]({ForumsLink}) @@ -675,15 +999,17 @@ Angular Virtual Scroll は、他のコンポーネントへの依存関係を持 - [List](../list.mdx) - 短いリストや、仮想化されたリストのコンテナーとして List を使用します。 -- [Card](../card.mdx) - リッチなアイテムの少量のセット、または水平の Virtual Scroll のアイテムとしてカードを使用します。 +- [Data Grid](../grid/grid.mdx) - 列、ソート、フィルタリングを伴う表形式のデータには Data Grid を使用します。 +- [Card](../card.mdx) - 少数のリッチなアイテムの表示や、水平方向の Virtual Scroll のアイテムとしてカードを使用します。 - [Virtual ForOf ディレクティブ](../for-of.mdx) - 既存のリストで使用されるディレクティブ ベースの仮想化。 - + - [List](../grids/list.mdx) - 短いリストや、仮想化されたリストのコンテナーとして List を使用します。 -- [Card](./card.mdx) - リッチなアイテムの少量のセット、または水平の Virtual Scroll のアイテムとしてカードを使用します。 +- [Data Grid](../grids/data-grid.mdx) - 列、ソート、フィルタリングを伴う表形式のデータには Data Grid を使用します。 +- [Card](./card.mdx) - 少数のリッチなアイテムの表示や、水平方向の Virtual Scroll のアイテムとしてカードを使用します。 @@ -695,6 +1021,9 @@ Angular Virtual Scroll は、他のコンポーネントへの依存関係を持 {Platform} Virtual Scroll のアイテムは、レンダリングされた時点でそれぞれが測定されるため、異なるサイズにすることができます。アイテムが測定される前にスクロールバーを正確に保つため、`estimatedItemSize` をアイテムの平均サイズに近い値に設定してください。 + + アイテムが測定されると、まだ測定されていないアイテムの推定値は測定済みの平均サイズに置き換えられます。 + {Platform} Virtual Scroll の `scrollToIndex` メソッドを、アイテムのインデックスと、省略可能な `block` および `behavior` オプションを指定して呼び出します。このメソッドは、補正された位置が安定すると解決されるプロミスを返します。 @@ -706,5 +1035,9 @@ Angular Virtual Scroll は、他のコンポーネントへの依存関係を持 {Platform} Virtual Scroll は、`igcDataRequest` イベントを通じて追加専用の読み込みをサポートします。イベントを処理し、要求されたアイテムを含む新しい配列を `data` に割り当てます。 + + + {Platform} Virtual Scroll は `onDataRequest` イベントによる追加のみの読み込みをサポートします。イベントを処理し、要求されたアイテムを含む新しい配列を `data` に割り当てます。 + diff --git a/docs/xplat/src/content/jp/toc.json b/docs/xplat/src/content/jp/toc.json index b00c92cffb..31cf98fbf9 100644 --- a/docs/xplat/src/content/jp/toc.json +++ b/docs/xplat/src/content/jp/toc.json @@ -2595,7 +2595,6 @@ }, { "exclude": [ - "React", "Blazor" ], "name": "仮想スクロール",