<Carousel> holds the strip of items, <Carousel.Item> wraps each slide, and <Carousel.Caption> positions text over it. Left alone it advances every five seconds; pass activeIndex and onSelect and the current slide becomes your state, which you need as soon as anything else on the page cares what is showing. The demo runs with no build step: an import map resolves the bare specifiers and @babel/standalone compiles the JSX.
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css">
<div id="root" class="p-3"></div>
<script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
<script type="importmap">{"imports": {
"react": "https://esm.sh/react@19.3.0",
"react/jsx-runtime": "https://esm.sh/react@19.3.0/jsx-runtime",
"react-dom": "https://esm.sh/react-dom@19.3.0",
"react-dom/client": "https://esm.sh/react-dom@19.3.0/client",
"react-bootstrap": "https://esm.sh/react-bootstrap@2.10.10?external=react,react-dom"
}}</script>
<script type="text/babel" data-type="module">
import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
import { Carousel } from 'react-bootstrap';
const slides = [['Split keyboards', '#1565c0'], ['Studio monitors', '#2e7d32'],
['Braided cables', '#6a1b9a']];
function Gallery() {
const [i, setI] = useState(0);
return (
<Carousel activeIndex={i} onSelect={setI} interval={null}>
{slides.map(([name, color]) => (
<Carousel.Item key={name}>
<div style={{ height: 150, background: color }} />
<Carousel.Caption><h3 className="h5">{name} ({i + 1} of 3)</h3></Carousel.Caption>
</Carousel.Item>))}
</Carousel>);
}
createRoot(document.getElementById('root')).render(<Gallery />);
</script>
onSelect receives the index being moved to, so setI alone keeps the pair in sync. Other props: interval in milliseconds, pause="hover" (the default) or pause={false}, fade for a cross-fade, controls={false} and indicators={false} to drop the chrome, and touch for swipes.
Carousels are hostile to accessibility: content moves without user intent, and a screen reader can be read a slide that has already rotated away. The indicators are real buttons and the controls take prevLabel and nextLabel, but ask first whether a grid showing every item serves the reader better.