Open darynl opened 2 years ago
I am facing the same issue. From a little research, it comes from this part of the code in CarouselItem.tsx
:
// Handle animation directions and opacity given based on active, prevActive and this item's index
const { active, next: isNext, prevActive } = state;
let animate = 'center';
if (index === active) {
animate = 'center';
} else if (index === prevActive) {
animate = isNext ? 'leftwardExit' : 'rightwardExit';
if (active === maxIndex && index === 0) animate = 'rightwardExit';
if (active === 0 && index === maxIndex) animate = 'leftwardExit';
} else {
animate = index < active ? 'leftOut' : 'rightOut';
if (active === maxIndex && index === 0) animate = 'rightOut';
if (active === 0 && index === maxIndex) animate = 'leftOut';
}
I have been trying to debug without success as I am not very experienced with framer-motion
, from what I understand the issue comes from the fact that when only 2 items are provided, the previous and the next element becomes the same which is not handled by the bool
logic above, only allowing an item to be a prev or a next.
I stumbled across this example that is using some pagination, but my knowledge with those libs is too limited to create a PR.
Interested to collaborate on the matter though.
I actually came up with a quick hack to handle this, using a local version of the package. But I don't think it is a viable solution.
In Carousel.tsx
:
[...]
let sanitizedProps = sanitizeProps(props);
let doubled = false;
if (Array.isArray(sanitizedProps.children) && sanitizedProps.children.length === 2) {
sanitizedProps = { ...sanitizedProps, children: [...sanitizedProps.children, ...sanitizedProps.children] };
doubled = true;
}
[...]
{indicators ? (
<Indicators
length={Array.isArray(children) ? children.length / (doubled ? 2 : 1) : 0}
active={doubled ? state.active % 2 : state.active}
press={setNext}
indicatorContainerProps={indicatorContainerProps}
indicatorIconButtonProps={indicatorIconButtonProps}
activeIndicatorIconButtonProps={activeIndicatorIconButtonProps}
IndicatorIcon={IndicatorIcon}
/>
) : null}
When I attempted to npm install
the fork of ted537 #194 it couldn't find the module.
I removed /dist from .gitignore and ran npm run build
on my fork so it should be able to used directly by doing npm install https://github.com/AchillesTurtle/react-material-ui-carousel
I also changed the code a bit since the last solution makes the prevActive disappear instantly on click which is a little weird visually.
// Handle animation directions and opacity given based on active, prevActive and this item's index
const { active, next: isNext, prevActive } = state;
let animate = 'center';
if (index === active)
animate = 'center';
else if (index === prevActive)
{
animate = isNext ? 'leftwardExit' : 'rightwardExit';
if (maxIndex > 1) {
if (active === maxIndex && index === 0) animate = 'rightwardExit';
if (active === 0 && index === maxIndex) animate = 'leftwardExit'
}
}
else
{
animate = index < active ? 'leftOut' : 'rightOut';
if (maxIndex > 1) {
if (active === maxIndex && index === 0) animate = 'rightOut';
if (active === 0 && index === maxIndex) animate = 'leftOut';
}
}
This handles slides as I wanted it to, but when setting cycleNavigation={true} it kind of shuffles instead which is not ideal.
If there are only two items, the carousel slides the wrong direction.