[Slider] Setting it as relative to a container is not working
See original GitHub issueI am building my own image carousel component. I am using Slide component to slide in/out images. Setting it’s container property using react ref to carousel container div so that images will start transitioning from edge of that reference element, however its not working and images always start transitioning from edge of computer screen (right/left)
here is my code - AppCarousel.js
`import React, { useReducer, useEffect, useRef, cloneElement } from ‘react’; import styled from ‘styled-components’; import { ChevronLeft, ChevronRight } from ‘components/global/Icons’; import { Slide } from ‘@material-ui/core’;
/* TODO:
-
- Add swipe controls for mobile.
-
- Add prop override for removing button controls
-
- Add interval timer for auto-rotate carousel items (including pause timer on hover) */
const reducer = (itemCount) => (state, action) => { switch (action.type) { case ‘exact’: if (state.currentItem !== action.payload) { return { currentItem: action.payload }; } return state; case ‘next’: return state.currentItem === itemCount - 1 ? { currentItem: 0, direction: ‘left’ } : { currentItem: state.currentItem + 1, direction: ‘left’ }; case ‘previous’: return state.currentItem === 0 ? { currentItem: itemCount - 1, direction: ‘right’ } : { currentItem: state.currentItem - 1, direction: ‘right’ }; default: console.error(‘Failed to load item.’); break; } };
const AppCarousel = ({ children, className, options = {} }) => { const { disableControls, activeIndex = 0 } = options; const itemCount = React.Children.count(children); const containerRef = useRef(null); const childItems = React.Children.toArray(children); const [state, dispatch] = useReducer(reducer(itemCount), { currentItem: activeIndex < itemCount && activeIndex > -1 ? activeIndex : 0, direction: ‘right’ });
const loadPrevItem = () => {
if (!disableControls) {
dispatch({ type: 'previous' });
}
};
const loadNextItem = () => {
if (!disableControls) {
dispatch({ type: 'next' });
}
};
const loadTargetItem = (index) => {
if (!disableControls) {
dispatch({ type: 'exact', payload: index });
}
};
const handleKeys = (key) => {
switch (key) {
case 'ArrowLeft':
loadPrevItem();
break;
case 'ArrowRight':
loadNextItem();
break;
default:
break;
}
};
return (
<StyledCarouselWrapper
aria-label='Carousel Control'
tabIndex={0}
onKeyDown={(e) => handleKeys(e.key)}
onClick={childItems[state.currentItem]?.onClick}
className={className}
>
<StyledFlexRow>
<StyledLeftArrowButton
id='prev-button'
aria-label='Show previous item'
aria-controls='content-area'
onClick={loadPrevItem}
disabled={disableControls}
>
<ChevronLeft />
</StyledLeftArrowButton>
<StyledContentArea
id='content-area'
aria-label='Content display area'
role='presentation'
itemCount={itemCount}
currentItem={state.currentItem}
ref={containerRef}
>
{/* <Slide direction='right' in timeout={1000}>
{childItems[state.currentItem]}
</Slide> */}
{cloneElement(childItems[state.currentItem], {
ref: containerRef,
direction: state.direction
})}
{/* {childItems[state.currentItem]} */}
</StyledContentArea>
<StyledRightArrowButton
id='next-button'
aria-label='Show next item'
aria-controls='content-area'
onClick={loadNextItem}
disabled={disableControls}
>
<ChevronRight />
</StyledRightArrowButton>
</StyledFlexRow>
<BubbleNav
childItems={childItems}
onClick={loadTargetItem}
currentItem={state.currentItem}
disabled={disableControls}
/>
</StyledCarouselWrapper>
);
};
export const AppCarouselItem = React.forwardRef( ({ children, direction }, ref) => { console.log('Ref ', ref); return ( <Slide direction={direction} in //timeout={1000} container={ref.current} // mountOnEnter // unmountOnExit > <ChildContainer>{children}</ChildContainer> </Slide> ); } );
const ChildContainer = React.forwardRef((props, ref) => { return ( <div ref={ref} {…props}> {props.children} </div> ); });
const BubbleNav = ({ childItems, onClick, currentItem, disabled }) => (
<StyledBubbleWrapper
aria-label='Item navigation'
aria-controls='content-area'
>
{childItems.map((item, index) => {
return (
<StyledDot
key={index}
index={index}
id={carousel-item-${index}
}
aria-label={
item?.ariaLabel ? item.ariaLabel : Item ${index}
}
onClick={() => onClick(index)}
currentItem={currentItem}
disabled={disabled}
></StyledDot>
);
})}
</StyledBubbleWrapper>
);
export default AppCarousel;
const StyledDot = styled.div background-color: ${({ index, currentItem, theme }) => index === currentItem ? theme.carousel.bubbleColorSelected : theme.carousel.bubbleColor}; border-radius: 0.3rem; width: 0.6rem; height: 0.6rem; margin: 0 0.2rem 0; opacity: ${({ disabled }) => (disabled ? 0.5 : 1)}; :hover { cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')}; }
;
const StyledBubbleWrapper = styled.div display: flex; align-self: center; margin-top: 0.5rem;
;
const StyledCarouselWrapper = styled.div display: flex; flex-direction: column; justify-content: space-around;
;
const StyledFlexRow = styled.div display: flex; flex-direction: row; align-self: center;
;
const StyledContentArea = styled.div display: flex; background-color: ${({ theme }) => theme.carousel.contentBackgroundColor}; min-width: ${({ itemCount }) =>
${1 * itemCount}rem}; * { display: inline-flex; justify-content: center; align-items: center; padding: 0; margin: 0; } justify-content: center; height: fit-content; white-space: nowrap;
;
const StyledArrowButton = styled.button color: ${({ theme }) => theme.carousel.navigationArrowColor}; z-index: 1; background: none; border: none; align-self: center; height: fit-content; font-size: ${({ theme }) => theme.iconSizeSmall}; opacity: ${({ disabled }) => (disabled ? 0.5 : 1)}; :hover, :focus { cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')}; } & i::before { font-weight: bolder; }
;
const StyledLeftArrowButton = styled(StyledArrowButton) margin-right: 1rem;
;
const StyledRightArrowButton = styled(StyledArrowButton) margin-left: 1rem;
;
`
Issue Analytics
- State:
- Created a year ago
- Comments:9 (2 by maintainers)
Top GitHub Comments
@Tanmay2711 I also faced the same trouble and it took my day.
I must be too late for you but put the solution for others.
Please add the style
overflow: hidden
to the container DOM.Document makes it sound as all you need to do is only specifying
container
props, but in fact you also need to setoverflow
style to the container DOM.ref) https://stackoverflow.com/a/69787498
@danilo-leal I think the documentation is misleading and should be improved so that it is clear that
overflow: hidden
is required.And, this issue is not about Slider but Slide.
Since the issue is missing key information, and has been inactive for 7 days, it has been automatically closed. If you wish to see the issue reopened, please provide the missing information.