InfiniteScrollArea
InfiniteScrollAreaは、無限スクロール機能を提供するコンポーネントです。このコンポーネントは、コンポーネントの終わりに達したときに次のデータセットを自動的に読み込み、表示することで、スムーズなスクロール体験を提供します。
const [count, setCount] = useState<number>(50)
return (
<InfiniteScrollArea
loading={<Loading.Oval fontSize="2xl" />}
onLoad={({ finish, index }) => {
console.log("load", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
}}
>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
)
"use client"をファイルの上部に追加する必要があります。使い方
import { InfiniteScrollArea } from "@yamada-ui/react"
import { InfiniteScrollArea } from "@/components/ui"
import { InfiniteScrollArea } from "@workspace/ui"
<InfiniteScrollArea />
ビューポートを指定する
ビューポートを指定する場合は、rootRefにrefを設定します。
rootRefが設定されない場合は、ブラウザのビューポートが使用されます。const rootRef = useRef<HTMLDivElement>(null)
const [count, setCount] = useState<number>(50)
const resetRef = useRef<() => void>(noop)
return (
<VStack h="full" alignItems="flex-start">
<VStack
ref={rootRef}
borderWidth="1px"
overflowY="auto"
p="lg"
h="sm"
rounded="l2"
>
<InfiniteScrollArea
loading={<Loading.Oval fontSize="2xl" />}
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) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
</VStack>
<Button
onClick={() => {
setCount(50)
resetRef.current()
}}
>
Reset
</Button>
</VStack>
)
"use client"をファイルの上部に追加する必要があります。rootMarginを設定する
rootMarginを設定する場合は、rootMarginに文字列を設定します。
const [count, setCount] = useState<number>(50)
return (
<InfiniteScrollArea
rootMargin="300px 0px 0px 0px"
loading={<Loading.Oval fontSize="2xl" />}
onLoad={({ finish, index }) => {
console.log("load", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
}}
>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
)
"use client"をファイルの上部に追加する必要があります。thresholdを設定する
thresholdを設定する場合は、thresholdに数値を設定します。
const [count, setCount] = useState<number>(50)
return (
<InfiniteScrollArea
threshold={1}
loading={<Loading.Oval fontSize="2xl" />}
onLoad={({ finish, index }) => {
console.log("load", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
}}
>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
)
"use client"をファイルの上部に追加する必要があります。初回に読み込む
初回に読み込む場合は、initialLoadをtrueに設定します。デフォルトでは、initialLoadがfalseに設定されており、初回(index=0)のonLoadは実行されません。
true: スクロール量に関わらず、初回のonLoadは実行され、提供されるindexは0から始まります。
false: スクロールが一定に達するとonLoadが実行され、提供されるindexは1から始まります。
const [count, setCount] = useState<number>(50)
return (
<InfiniteScrollArea
initialLoad
loading={<Loading.Oval fontSize="2xl" />}
onLoad={({ finish, index }) => {
console.log("load", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
}}
>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
)
"use client"をファイルの上部に追加する必要があります。開始するindexを変更する
開始するindexを変更する場合は、startIndexに数値を設定します。デフォルトでは、1が設定されています。
const [count, setCount] = useState<number>(50)
return (
<InfiniteScrollArea
startIndex={3}
loading={<Loading.Oval fontSize="2xl" />}
onLoad={({ finish, index }) => {
console.log("load", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
}}
>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
)
"use client"をファイルの上部に追加する必要があります。方向を変更する
方向を変更する場合は、orientationに"vertical"または"horizontal"を設定します。デフォルトは、"vertical"です。
const [count, setCount] = useState<number>(50)
return (
<>
{Array(count)
.fill(0)
.map((_, index) => (
<Image
borderWidth="1px"
rounded="l2"
key={index}
src="https://gurren-lagann15th.com/assets/img/top/visual.jpg"
w="sm"
h="full"
objectFit="cover"
/>
))}
</>
)
"use client"をファイルの上部に追加する必要があります。反転させる
反転させる場合は、reverseをtrueに設定します。デフォルトは、falseです。
const rootRef = useRef<HTMLDivElement>(null)
const [count, setCount] = useState<number>(50)
return (
<Box ref={rootRef} h="full" overflow="auto">
<InfiniteScrollArea
reverse
rootRef={rootRef}
loading={<Loading.Oval fontSize="2xl" />}
onLoad={({ finish, index }) => {
console.log("load", index)
setCount((prev) => prev + 50)
if (index >= 5) finish()
}}
>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
</Box>
)
"use client"をファイルの上部に追加する必要があります。無効にする
無効にする場合は、disabledをtrueに設定します。これは、特定の条件下でスクロールに合わせてonLoadを実行したくない場合に有効です。
const [disabled, setDisabled] = useState<boolean>(false)
const [count, setCount] = useState<number>(50)
return (
<VStack h="full" alignItems="flex-start">
<InfiniteScrollArea
disabled={disabled}
loading={<Loading.Oval fontSize="2xl" />}
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) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
<Button
colorScheme={disabled ? "success" : "danger"}
onClick={() => setDisabled((prev) => !prev)}
>
{disabled ? "Enable" : "Disabled"}
</Button>
</VStack>
)
"use client"をファイルの上部に追加する必要があります。リセットする
indexをリセットする場合は、resetRefにrefを設定します。設定されたrefにコールバック関数が付与されるので、それを実行します。
resetRefのコールバックを実行すると、スクロールもリセットされます。const resetRef = useRef<() => void>(noop)
const [count, setCount] = useState<number>(50)
return (
<VStack h="full" alignItems="flex-start">
<InfiniteScrollArea
resetRef={resetRef}
loading={<Loading.Oval fontSize="2xl" />}
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) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
<Button
onClick={() => {
setCount(50)
resetRef.current()
}}
>
Reset
</Button>
</VStack>
)
"use client"をファイルの上部に追加する必要があります。スクロールの終わりに要素を表示する
スクロールの終わりに要素を表示する場合は、finishにReactNodeを設定します。
const [count, setCount] = useState<number>(50)
return (
<InfiniteScrollArea
finish={<>俺のドリルは!天を作るドリルだああああっ!!</>}
loading={<Loading.Oval fontSize="2xl" />}
onLoad={({ finish, index }) => {
console.log("load", index)
setCount((prev) => prev + 50)
if (index >= 1) finish()
}}
>
{Array(count)
.fill(0)
.map((_, index) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
)
"use client"をファイルの上部に追加する必要があります。トリガーをカスタマイズする
トリガーをカスタマイズする場合は、triggerPropsにpropsを設定します。
const [count, setCount] = useState<number>(50)
return (
<InfiniteScrollArea
triggerProps={{
bg: "primary.50",
p: "md",
rounded: "md",
}}
loading={<Loading.Oval fontSize="2xl" />}
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) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
)
"use client"をファイルの上部に追加する必要があります。ローディングをカスタマイズする
ローディングをカスタマイズする場合は、loadingにReactNodeを設定します。
const [count, setCount] = useState<number>(50)
return (
<InfiniteScrollArea
loading={<>一回転すればほんの少しだけ前に進む、それがドリルなんだよ!!</>}
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) => (
<Card.Root key={index}>
<Card.Header>
<Heading size="xl">天元突破グレンラガン</Heading>
</Card.Header>
<Card.Body>
<Text>
いいか、忘れんな。お前を信じろ。俺が信じるお前でもない。お前が信じる俺でもない。お前が信じる…お前を信じろ!
</Text>
</Card.Body>
</Card.Root>
))}
</InfiniteScrollArea>
)
"use client"をファイルの上部に追加する必要があります。