Slide
The slide transition is usually used for creating a carousel which animates different panels into view horizontally.
Simple Example
The slide transition can be created by using a SlideContainer
and Slide
components. The SlideContainer
requires the transition direction
prop and
each Slide
requires an active
state to trigger the transition.
"use client";
import { Box } from "@react-md/core/box/Box";
import { SegmentedButton } from "@react-md/core/segmented-button/SegmentedButton";
import { SegmentedButtonContainer } from "@react-md/core/segmented-button/SegmentedButtonContainer";
import { Slide } from "@react-md/core/transition/Slide";
import {
SlideContainer,
type SlideDirection,
} from "@react-md/core/transition/SlideContainer";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement, useState } from "react";
interface State {
page: 1 | 2 | 3;
direction: SlideDirection;
}
export default function SimpleExample(): ReactElement {
const [state, setState] = useState<State>({
page: 1,
direction: "forward",
});
const { page, direction } = state;
const setPage = (page: 1 | 2 | 3): void => {
setState((prev) => ({
page,
direction: prev.page < page ? "forward" : "backward",
}));
};
return (
<Box stacked fullWidth>
<SegmentedButtonContainer>
<SegmentedButton
selected={page === 1}
onClick={() => {
setPage(1);
}}
>
Page 1
</SegmentedButton>
<SegmentedButton
selected={page === 2}
onClick={() => {
setPage(2);
}}
>
Page 2
</SegmentedButton>
<SegmentedButton
selected={page === 3}
onClick={() => {
setPage(3);
}}
>
Page 3
</SegmentedButton>
</SegmentedButtonContainer>
<SlideContainer direction={direction}>
<Slide active={page === 1}>
<Typography type="headline-4">Page 1</Typography>
</Slide>
<Slide active={page === 2}>
<Typography type="headline-4">Page 2</Typography>
</Slide>
<Slide active={page === 3}>
<Typography type="headline-4">Page 3</Typography>
</Slide>
</SlideContainer>
</Box>
);
}
Vertical
The slide transition can also be vertical instead of horizontal by enabling the vertical
prop.
"use client";
import { Box } from "@react-md/core/box/Box";
import { SegmentedButton } from "@react-md/core/segmented-button/SegmentedButton";
import { SegmentedButtonContainer } from "@react-md/core/segmented-button/SegmentedButtonContainer";
import { Slide } from "@react-md/core/transition/Slide";
import {
SlideContainer,
type SlideDirection,
} from "@react-md/core/transition/SlideContainer";
import { Typography } from "@react-md/core/typography/Typography";
import { type ReactElement, useState } from "react";
interface State {
page: 1 | 2 | 3;
direction: SlideDirection;
}
export default function VerticalExample(): ReactElement {
const [state, setState] = useState<State>({
page: 1,
direction: "forward",
});
const { page, direction } = state;
const setPage = (page: 1 | 2 | 3): void => {
setState((prev) => ({
page,
direction: prev.page < page ? "forward" : "backward",
}));
};
return (
<Box stacked fullWidth>
<SegmentedButtonContainer>
<SegmentedButton
selected={page === 1}
onClick={() => {
setPage(1);
}}
>
Page 1
</SegmentedButton>
<SegmentedButton
selected={page === 2}
onClick={() => {
setPage(2);
}}
>
Page 2
</SegmentedButton>
<SegmentedButton
selected={page === 3}
onClick={() => {
setPage(3);
}}
>
Page 3
</SegmentedButton>
</SegmentedButtonContainer>
<SlideContainer direction={direction} vertical>
<Slide active={page === 1}>
<Typography>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec
feugiat diam et mauris dapibus bibendum. Praesent vehicula maximus
egestas. Mauris lacinia lectus elit, quis placerat massa egestas sit
amet. Sed massa ex, commodo sed orci nec, accumsan sagittis sem.
Curabitur malesuada urna sit amet leo vehicula lobortis.
Pellentesque habitant morbi tristique senectus et netus et malesuada
fames ac turpis egestas. Integer fringilla tincidunt nunc, in
efficitur nibh placerat quis. Vivamus a est quis nunc vestibulum
facilisis. Ut ut massa a ante ultricies imperdiet. Orci varius
natoque penatibus et magnis dis parturient montes, nascetur
ridiculus mus. Ut viverra volutpat ex, eu scelerisque tortor
interdum non. Ut cursus mi id turpis tristique, sed fringilla urna
fermentum. Suspendisse potenti. Suspendisse hendrerit scelerisque
porttitor. Duis nisi dolor, ultrices quis fermentum ac, interdum eu
nisl.
</Typography>
</Slide>
<Slide active={page === 2}>
<Typography>
Donec nec ultricies tellus. Suspendisse potenti. Cras condimentum,
arcu tempus ornare aliquet, purus elit bibendum justo, eu pretium
mauris leo ac ligula. Sed imperdiet odio in vulputate vestibulum.
Integer vitae commodo elit. Phasellus gravida eros at dolor varius,
in tempor metus tincidunt. Nulla dictum nec mi in dignissim. Duis
non mauris a turpis posuere tempor ut vel eros. Donec volutpat velit
sapien, et varius velit viverra sit amet. Aenean id magna sit amet
velit rutrum porta in a tortor. Integer vel feugiat tortor. Nullam
posuere, nulla ut viverra dignissim, eros quam mattis erat, eget
pretium felis erat non mi. Proin varius est id pretium volutpat.
Aliquam erat volutpat.
</Typography>
</Slide>
<Slide active={page === 3}>
<Typography>
Mauris porta mauris et feugiat blandit. Sed placerat non mauris at
ultrices. Fusce malesuada sem ut nulla malesuada aliquam.
Pellentesque fermentum aliquam lorem, at semper ex facilisis ac.
Fusce laoreet odio vitae sem dictum, at sagittis erat imperdiet.
Nullam lacinia tortor at diam tempus malesuada. Aliquam vitae
euismod mi. Integer ac enim commodo felis sollicitudin condimentum
id at ex. Mauris lobortis est nunc, et scelerisque eros malesuada
vel.
</Typography>
</Slide>
</SlideContainer>
</Box>
);
}
Preventing Layout Shifts
When the Slide
content have different heights, the layout might shift when
the animation completes to match the current content's height. If this
behavior isn't desired, check out the
useMaxTabPanelHeight hook and
Use Max Tab Panel Height demo.