Carousel
Carouselは、複数の要素をスライドショーのように表示するコンポーネントです。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
使い方
import { Carousel } from "@yamada-ui/react"
import { Carousel } from "@/components/ui"
import { Carousel } from "@workspaces/ui"
<Carousel.Root>
<Carousel.List>
<Carousel.Item />
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators>
<Carousel.Indicator />
</Carousel.Indicators>
</Carousel.Root>
Carouselは、内部でembla-carousel-reactを使用しています。サイズを変更する


















const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<VStack>
<For each={["sm", "md", "lg"]}>
{(size, key) => (
<Carousel.Root key={key} size={size}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)}
</For>
</VStack>
)
カラースキームを変更する












const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<VStack>
<For each={["success", "warning"]}>
{(colorScheme, key) => (
<Carousel.Root key={key} colorScheme={colorScheme}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)}
</For>
</VStack>
)
方向を変更する
方向を変更する場合は、orientationに"horizontal"または"vertical"を設定します。デフォルトでは、"horizontal"が設定されています。












const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<VStack>
<For each={["horizontal", "vertical"]}>
{(orientation, key) => (
<Carousel.Root key={key} orientation={orientation}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)}
</For>
</VStack>
)
デフォルトのスライドを選択する
デフォルトのスライドを選択する場合は、defaultIndexにindexを設定します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root defaultIndex={1}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
スライド間を調整する
スライド間を調整する場合は、gapに文字列または数値を設定します。デフォルトでは、1remが設定されています。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root gap="0">
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
スライドが切り替わる所要時間を変更する
スライドが切り替わる所要時間を変更する場合は、durationに数値を設定します。デフォルトでは、25が設定されています。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root duration={60}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
スライドのサイズを変更する
スライドのサイズを変更する場合は、slideSizeに文字列または数値を設定します。デフォルトでは、100%が設定されています。
もし、個別のスライドのサイズを変更する場合は、Carousel.ItemのslideSizeに値を設定します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root slideSize="50%">
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
index={index}
slideSize={index === 1 ? "100%" : undefined}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
スライドの位置を変更する
スライドの位置を変更する場合は、alignに"start", "center", "end"または数値を設定します。デフォルトでは、"center"が設定されています。


















const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<VStack>
<For each={["center", "start", "end"]}>
{(align, key) => (
<Carousel.Root key={key} slideSize="50%" align={align}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)}
</For>
</VStack>
)
スライドをスクロールする数を変更する
スライドをスクロールする数を変更する場合は、slidesToScrollに数値を設定します。デフォルトでは、1が設定されています。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root slideSize={`${100 / 3}%`} slidesToScroll={3}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
自動再生を使う
自動再生を使う場合は、autoplayをtrueに設定します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root autoplay>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
index={index}
slideSize={index === 1 ? "100%" : undefined}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
自動再生の間隔を変更する
自動再生の間隔を変更する場合は、delayに数値(ミリ秒)を設定します。デフォルトでは、4000が設定されています。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root autoplay delay={1000}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
index={index}
slideSize={index === 1 ? "100%" : undefined}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
自動再生を停止しない
デフォルトでは、要素上にホバーされたとき自動再生は停止します。停止しない場合は、stopMouseEnterAutoplayをfalseに設定します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root autoplay stopMouseEnterAutoplay={false}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
index={index}
slideSize={index === 1 ? "100%" : undefined}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
ドラッグフリーを使う
ドラッグフリーを使う場合は、dragFreeをtrueに設定します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root dragFree>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
index={index}
slideSize={index === 1 ? "100%" : undefined}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
ループを無効にする
ループを無効にする場合は、loopをfalseに設定します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root loop={false}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
index={index}
slideSize={index === 1 ? "100%" : undefined}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
ドラッグを無効にする
ドラッグを無効にする場合は、draggableをfalseに設定します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root draggable={false}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
index={index}
slideSize={index === 1 ? "100%" : undefined}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
コントロールボタンをカスタマイズする
コントロールボタンをカスタマイズする場合は、Carousel.PrevTriggerやCarousel.NextTriggerにpropsを設定します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
index={index}
slideSize={index === 1 ? "100%" : undefined}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger
bottom="4"
icon={<ArrowLeftIcon />}
top="unset"
transform="unset"
/>
<Carousel.NextTrigger
bottom="4"
icon={<ArrowRightIcon />}
top="unset"
transform="unset"
/>
<Carousel.Indicators />
</Carousel.Root>
)
インジケーターをカスタマイズする
インジケーターをカスタマイズする場合は、Carousel.Indicatorsにpropsを設定します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
index={index}
slideSize={index === 1 ? "100%" : undefined}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators
h="6"
render={({ selected }) => (
<Center as="button" cursor="pointer">
<CircleIcon
data-selected={dataAttr(selected)}
color="transparent"
fill="colorScheme.solid/40"
fontSize="2xl"
_selected={{
fill: "colorScheme.solid",
}}
_hover={{
_notSelected: {
fill: "colorScheme.solid/70",
},
}}
/>
</Center>
)}
/>
</Carousel.Root>
)
イベントをハンドルする
ユーザーのドラッグなどのイベントをハンドルする場合は、watchDragを使用します。






const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<Carousel.Root
watchDrag={(methods, ev) => {
console.log("drag", methods, ev)
return true
}}
watchResize={(methods, entries) => {
console.log("resized", methods, entries)
return true
}}
watchSlides={(methods, mutations) => {
console.log("slides updated", methods, mutations)
return true
}}
>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
)
制御する





State
Ref
const controlRef = useRef<Carousel.Control>(null)
const [index, setIndex] = useState(0)
const [sources, setSources] = useState([
"https://www.ghibli.jp/gallery/baron001.jpg",
"https://www.ghibli.jp/gallery/baron002.jpg",
"https://www.ghibli.jp/gallery/baron003.jpg",
"https://www.ghibli.jp/gallery/baron004.jpg",
"https://www.ghibli.jp/gallery/baron005.jpg",
])
return (
<VStack>
<Carousel.Root controlRef={controlRef} index={index} onChange={setIndex}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
<ButtonGroup.Root>
<ButtonGroup.Item
disabled={sources.length === 50}
onClick={() => {
const num = (sources.length + 1).toString().padStart(2, "0")
const nextSources = [
...sources,
`https://www.ghibli.jp/gallery/baron0${num}.jpg`,
]
setSources(nextSources)
setIndex(nextSources.length - 1)
}}
>
Add
</ButtonGroup.Item>
<ButtonGroup.Item
disabled={sources.length === 1}
onClick={() => {
if (index === sources.length - 1) setIndex((prev) => prev - 1)
setSources(sources.slice(0, -1))
}}
>
Remove
</ButtonGroup.Item>
</ButtonGroup.Root>
<VStack gap="sm">
<Text>State</Text>
<ButtonGroup.Root>
<ButtonGroup.Item onClick={() => setIndex(0)}>Home</ButtonGroup.Item>
<ButtonGroup.Item
onClick={() =>
setIndex((prev) => (prev === 0 ? sources.length - 1 : prev - 1))
}
>
Prev
</ButtonGroup.Item>
<ButtonGroup.Item
onClick={() =>
setIndex((prev) => (prev === sources.length - 1 ? 0 : prev + 1))
}
>
Next
</ButtonGroup.Item>
<ButtonGroup.Item onClick={() => setIndex(sources.length - 1)}>
End
</ButtonGroup.Item>
</ButtonGroup.Root>
</VStack>
<VStack gap="sm">
<Text>Ref</Text>
<ButtonGroup.Root>
<ButtonGroup.Item onClick={() => controlRef.current?.scrollTo(0)}>
Home
</ButtonGroup.Item>
<ButtonGroup.Item onClick={() => controlRef.current?.scrollPrev()}>
Prev
</ButtonGroup.Item>
<ButtonGroup.Item onClick={() => controlRef.current?.scrollNext()}>
Next
</ButtonGroup.Item>
<ButtonGroup.Item
onClick={() => controlRef.current?.scrollTo(sources.length - 1)}
>
End
</ButtonGroup.Item>
</ButtonGroup.Root>
</VStack>
</VStack>
)
"use client"をファイルの上部に追加する必要があります。



































































































const [index, setIndex] = useState(0)
const sources = useMemo(
() =>
Array.from(
{
length: 50,
},
(_, index) => {
const num = (index + 1).toString().padStart(2, "0")
return `https://www.ghibli.jp/gallery/baron0${num}.jpg`
},
),
[],
)
return (
<VStack>
<Carousel.Root index={index} onChange={setIndex}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
</Carousel.Root>
<Carousel.Root
containScroll="keepSnaps"
dragFree
h="5xs"
index={index}
slideSize="20%"
>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item
key={index}
cursor="pointer"
index={index}
opacity="0.4"
_selected={{
opacity: 1,
}}
onClick={() => setIndex(index)}
>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
</Carousel.Root>
</VStack>
)
"use client"をファイルの上部に追加する必要があります。onScrollProgressを使用して、現在のスクロール量にアクセスできます。






const [progress, setProgress] = useState(0)
const sources = useMemo(
() => [
"https://www.ghibli.jp/gallery/chihiro015.jpg",
"https://www.ghibli.jp/gallery/howl049.jpg",
"https://www.ghibli.jp/gallery/totoro036.jpg",
"https://www.ghibli.jp/gallery/mononoke033.jpg",
"https://www.ghibli.jp/gallery/laputa047.jpg",
"https://www.ghibli.jp/gallery/porco025.jpg",
],
[],
)
return (
<VStack>
<Carousel.Root dragFree loop={false} onScrollProgress={setProgress}>
<Carousel.List>
{sources.map((src, index) => (
<Carousel.Item key={index} index={index}>
<Image
src={src}
alt="スタジオジブリ作品静止画"
boxSize="full"
objectFit="cover"
/>
</Carousel.Item>
))}
</Carousel.List>
<Carousel.PrevTrigger />
<Carousel.NextTrigger />
<Carousel.Indicators />
</Carousel.Root>
<Progress value={progress} />
</VStack>
)
"use client"をファイルの上部に追加する必要があります。Props
アクセシビリティ
現在、v2の移行に伴い、このセクションは更新中です。