--- title: InfiniteScrollArea description: "`InfiniteScrollArea` is a component that provides infinite scrolling functionality. This component offers a smooth scrolling experience by automatically loading and displaying the next dataset when the end of the component is reached." links: - style: https://github.com/yamada-ui/yamada-ui/tree/main/packages/react/src/components/infinite-scroll-area/infinite-scroll-area.style.ts - source: https://github.com/yamada-ui/yamada-ui/tree/main/packages/react/src/components/infinite-scroll-area - storybook: https://yamada-ui.github.io/yamada-ui?path=/story/components-infinitescrollarea--basic --- ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ## Usage ```tsx import { InfiniteScrollArea } from "@yamada-ui/react" ``` ```tsx import { InfiniteScrollArea } from "@/components/ui" ``` ```tsx import { InfiniteScrollArea } from "@workspace/ui" ``` ```tsx ``` ### Specify the Viewport To specify the viewport, set a `ref` to `rootRef`. :::note If `rootRef` is not set, the browser's viewport will be used. ::: ```tsx const rootRef = useRef(null) const [count, setCount] = useState(50) const resetRef = useRef<() => void>(noop) return ( } resetRef={resetRef} rootRef={rootRef} onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Set rootMargin To set [rootMargin](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#rootmargin), assign a string to rootMargin. ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Set threshold To set [threshold](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#threshold), assign a number to `threshold`. ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Initial Load To load initially, set `initialLoad` to `true`. By default, `initialLoad` is set to `false`, and the initial(`index=0`) `onLoad` is not executed. `true`: The first `onLoad` is executed regardless of the scroll amount, and the provided `index` starts from `0`.\ `false`: `onLoad` is executed when a certain scroll is reached, and the provided `index` starts from `1`. ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Change the Starting index To change the starting index, set a number to `startIndex`. The default is `1`. ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Change the Orientation To change the orientation, set `orientation` to either `"vertical"` or `"horizontal"`. The default is `"vertical"`. ```tsx const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( ))} ) ``` ### Reverse To reverse, set `reverse` to `true`. The default is `false`. ```tsx const rootRef = useRef(null) const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Disable To disable, set `disabled` to `true`. This is useful when you do not want to execute `onLoad` in response to scrolling under certain conditions. ```tsx const [disabled, setDisabled] = useState(false) const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} borderWidth="1px" h="sm" overflowY="auto" p="lg" rounded="l2" > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Reset To reset the `index`, set a `ref` to `resetRef`. A callback function is attached to the set `ref`, so execute it. :::warning Executing the `resetRef` callback will also reset the scroll. ::: ```tsx const resetRef = useRef<() => void>(noop) const [count, setCount] = useState(50) return ( } onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} borderWidth="1px" h="sm" overflowY="auto" p="lg" rounded="l2" > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Display an Element at the End of the Scroll To display an element at the end of the scroll, set a `ReactNode` to `finish`. ```tsx const [count, setCount] = useState(50) return ( 俺のドリルは!天を作るドリルだああああっ!!} loading={} onLoad={({ finish, index }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 1) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Customize the Trigger To customize the trigger, set props to `triggerProps`. ```tsx const [count, setCount] = useState(50) return ( } onLoad={async ({ finish, index }) => { console.log("load", index) await wait(5000) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ### Customize the Loading To customize the loading, set a `ReactNode` to `loading`. ```tsx const [count, setCount] = useState(50) return ( 一回転すればほんの少しだけ前に進む、それがドリルなんだよ!!} onLoad={async ({ finish, index }) => { console.log("load", index) await wait(5000) setCount((prev) => prev + 50) if (index >= 5) finish() }} > {Array(count) .fill(0) .map((_, index) => ( 天元突破グレンラガン いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ! ))} ) ``` ## Props | Prop | Default | Type | Description | | -------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | | `as` | - | `As` | The HTML element to render. | | `asChild` | - | `boolean` | Merges its props onto its immediate child. | | `css` | - | `CSSObject \| CSSObject[]` | The CSS object. | | `colorScheme` | - | `"amber" \| "black" \| "blackAlpha" \| "blue" \| "cyan" \| "danger" \| "emerald" \| "error" \| "flashy" \| "fuchsia" ...` | Set color scheme variables. | | `behavior` | - | `ScrollBehavior` | Determines whether scrolling is instant or animates smoothly. | | `disabled` | `false` | `boolean` | If `true`, the infinite scroll is disabled. | | `finish` | - | `ReactNode` | The infinite scroll area finish to use. | | `indexRef` | - | `RefObject<(index: number) => void>` | Ref to a reset index function. | | `initialLoad` | `false` | `boolean` | If `true`, invoke `onLoad` function for the first time. | | `loading` | - | `ReactNode` | The infinite scroll area loading to use. | | `onLoad` | - | `({ entry, finish, index }: { finish: () => void; index: number; entry?: IntersectionObserverEntry \| undefined }) => void \| Promise` | The callback invoked when trigger is intersect. | | `orientation` | `"vertical"` | `"horizontal" \| "vertical"` | The orientation of the infinite scroll. | | `resetRef` | - | `RefObject<(index?: number \| undefined, runScroll?: boolean \| undefined) => void>` | Ref to a reset function. | | `reverse` | `false` | `boolean` | If `true`, reverse direction. | | `rootMargin` | - | `string` | Margin around the root. Can have values similar to the CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). | | `rootRef` | - | `RefObject` | The element that is used as the viewport for checking visibility of the target. Defaults to the browser viewport if not specified or if `null`. | | `startIndex` | `1` | `number` | If set the `onLoad` function will start from the given index. If `initialLoad` is `true`, index starts from `0`. | | `threshold` | - | `number \| number[]` | Either a single number or an array of numbers which indicate at what percentage of the target's visibility the observer's callback should be executed. | | `triggerProps` | - | `HTMLStyledProps` | Props for infinite scroll area trigger component. |