InfiniteScrollArea
InfiniteScrollArea
は、無限スクロール機能を提供するコンポーネントです。このコンポーネントは、コンポーネントの終わりに達したときに次のデータセットを自動的に読み込み、表示することで、スムーズなスクロール体験を提供します。
インポート
import { InfiniteScrollArea } from "@yamada-ui/react"
使い方
編集可能な例
const [count, setCount] = useState<number>(50) return ( <InfiniteScrollArea onLoad={({ index, finish }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> )
ビューポートを指定する
ビューポートを指定する場合は、rootRef
にref
を設定します。
rootRef
が設定されない場合は、ブラウザのビューポートが使用されます。
編集可能な例
const rootRef = useRef<HTMLDivElement>(null) const [count, setCount] = useState<number>(50) const resetRef = useRef<() => void>(() => {}) return ( <VStack alignItems="flex-start" h="full"> <Container ref={rootRef} flex="1" borderWidth="1px" rounded="md" p="md" overflowY="auto" > <InfiniteScrollArea rootRef={rootRef} resetRef={resetRef} onLoad={ ({ index, finish }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} > <For each={Array.from({ length: count })}> {(_, index)=>( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> </Container> <Button onClick={() => resetRef.current()}>Reset</Button> </> )
rootMargin
を設定する
rootMarginを設定する場合は、rootMargin
に文字列を設定します。
編集可能な例
const [count, setCount] = useState<number>(50) return ( <InfiniteScrollArea onLoad={({ index, finish }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} rootMargin="300px 0px 0px 0px" > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> )
threshold
を設定する
thresholdを設定する場合は、threshold
に数値を設定します。
編集可能な例
const [count, setCount] = useState<number>(50) return ( <InfiniteScrollArea onLoad={({ index, finish }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} threshold={1} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> )
初回に読み込む
初回に読み込む場合は、initialLoad
をtrue
に設定します。デフォルトでは、initialLoad
がfalse
に設定されており、初回(index=0
)のonLoad
は実行されません。
true
: スクロール量に関わらず、初回のonLoad
は実行され、提供されるindex
は0
から始まります。
false
: スクロールが一定に達するとonLoad
が実行され、提供されるindex
は1
から始まります。
編集可能な例
const [count, setCount] = useState<number>(0) return ( <InfiniteScrollArea initialLoad onLoad={async ({ index, finish }) => { console.log("load", index) await wait(1000) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> )
開始するindex
を変更する
開始するindex
を変更する場合は、startIndex
に数値を設定します。デフォルトは、1
です。
編集可能な例
const [count, setCount] = useState<number>(50) return ( <InfiniteScrollArea onLoad={async ({ index, finish }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} startIndex={3} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> )
方向を変更する
方向を変更する場合は、orientation
にvertical
またはhorizontal
を設定します。デフォルトは、vertical
です。
編集可能な例
const [count, setCount] = useState<number>(50) return ( <InfiniteScrollArea orientation="horizontal" h="full" onLoad={({ index, finish }) => { setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index} minW="sm" h="full"> <CardHeader> <Heading size="md">『天元突破グレンラガン』</Heading> </CardHeader> <CardBody> <Image src="https://www.gurren-lagann.net/tv/images/kv.jpg" w="full" /> </CardBody> </Card> )} </For> </InfiniteScrollArea> )
反転させる
反転させる場合は、isReverse
をtrue
に設定します。デフォルトは、false
です。
編集可能な例
const rootRef = useRef<HTMLDivElement>(null) const [count, setCount] = useState<number>(50) return ( <Box ref={rootRef} h="full" overflow="auto"> <InfiniteScrollArea onLoad={({ index, finish }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} rootRef={rootRef} isReverse > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> </Box> )
無効にする
無効にする場合は、isDisabled
をtrue
に設定します。これは、特定の条件下でスクロールに合わせてonLoad
を実行したくない場合に有効です。
編集可能な例
const [isDisabled, setIsDisabled] = useState<boolean>(false) const [count, setCount] = useState<number>(50) return ( <VStack alignItems="flex-start" h="full"> <InfiniteScrollArea flex="1" borderWidth="1px" rounded="md" p="md" overflowY="auto" onLoad={async ({ index, finish }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} isDisabled={isDisabled} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> <Button colorScheme={isDisabled ? "success" : "danger"} onClick={() => setIsDisabled((prev) => !prev)} > {isDisabled ? "Enable" : "Disabled"} </Button> </VStack> )
リセットする
index
をリセットする場合は、resetRef
にref
を設定します。設定されたref
にコールバック関数が付与されるので、それを実行します。
resetRef
のコールバックを実行すると、スクロールもリセットされます。
編集可能な例
const resetRef = useRef<() => void>(() => {}) const [count, setCount] = useState<number>(50) return ( <VStack alignItems="flex-start" h="full"> <InfiniteScrollArea flex="1" borderWidth="1px" rounded="md" p="md" overflowY="auto" onLoad={async ({ index, finish }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} resetRef={resetRef} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> <Button onClick={() => resetRef.current()}>Reset</Button> </VStack> )
スクロールの終わりに要素を表示する
スクロールの終わりに要素を表示する場合は、finish
にReactNode
を設定します。
編集可能な例
const [count, setCount] = useState<number>(50) return ( <InfiniteScrollArea onLoad={({ index, finish }) => { console.log("load", index) setCount((prev) => prev + 50) if (index >= 1) finish() }} loading={<Loading fontSize="2xl" />} finish={<>Finished</>} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> )
トリガーをカスタマイズする
トリガーをカスタマイズする場合は、triggerProps
にprops
を設定します。
編集可能な例
const [count, setCount] = useState<number>(50) return ( <InfiniteScrollArea onLoad={async ({ index, finish }) => { console.log("load", index) await wait(5000) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<Loading fontSize="2xl" />} triggerProps={{ bg: "primary.50", p: "md", rounded: "md" }} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> )
ローディングをカスタマイズする
ローディングをカスタマイズする場合は、loading
にReactNode
を設定します。
編集可能な例
const [count, setCount] = useState<number>(50) return ( <InfiniteScrollArea onLoad={async ({ index, finish }) => { console.log("load", index) await wait(5000) setCount((prev) => prev + 50) if (index >= 5) finish() }} loading={<>Loading…</>} > <For each={Array.from({ length: count })}> {(_, index) => ( <Card key={index}> <CardHeader> <Heading size="md">俺を誰だと思っていやがるッ!!</Heading> </CardHeader> <CardBody> <Text> 『天元突破グレンラガン』は、ガイナックス・アニプレックス・コナミデジタルエンタテインメント製作の日本のロボットアニメ作品。 </Text> <Text> 作品名の「天元」とは、万物生育の根源という意味があり、また囲碁の用語では碁盤の中央(中心)を指す。劇中のキーワードにも螺旋、ドリル、回転など、中央・中心に関連するものが多く見られ、中央突破、王道路線を念頭に置いた作品名といえる。 </Text> </CardBody> </Card> )} </For> </InfiniteScrollArea> )
GitHubでこのページを編集する