Skip to content

Commit

Permalink
Carousel and SlideBox: add in new props to allow overflow on x, y, an… (
Browse files Browse the repository at this point in the history
#1458)

* Carousel and SlideBox: add in new props to allow overflow on x, y, and top

* Carousel, update overflow rules and storybooks

* Updates to Carousel stories

* Carousel, update arrowButton overflow fix

* Carousel: rename new prop from PR review suggestion
  • Loading branch information
ryan-hunt-priceline authored Feb 21, 2024
1 parent 7e175e5 commit 7f1b6e7
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "pcln-carousel",
"comment": "Carousel and SlideBox: add in new props to allow overflow to display on x, y, and top ",
"type": "minor"
}
],
"packageName": "pcln-carousel"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "pcln-design-system",
"comment": "SlideBox: add in new props to allow overflow to display on x, y and top",
"type": "minor"
}
],
"packageName": "pcln-design-system"
}
3 changes: 3 additions & 0 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/carousel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"jest-styled-components": "^7.1.1",
"npm-run-all": "^4.1.5",
"pcln-design-system": "workspace:*",
"pcln-popover": "workspace:*",
"pcln-icons": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/carousel/src/ArrowButton/ArrowButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ ArrowButton.propTypes = {
buttonSize: PropTypes.string,
/** When arrow position is side, hide arrows and shows when hovers on carousel */
showArrowsOnHover: PropTypes.bool,
/** adjust side arrow position for overflow */
overflowAdjust: PropTypes.number,
}

export { ArrowButton }
2 changes: 1 addition & 1 deletion packages/carousel/src/ArrowButton/ArrowButton.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const sidePositionStyles = (props) =>
${props.type == 'prev' ? 'left' : 'right'}: 0px;
position: absolute;
top: 50%;
margin-top: -30px;
margin-top: -${(props.overflowAdjust || 0) + 30}px;
z-index: 2;
${props.showArrowsOnHover &&
css`
Expand Down
27 changes: 26 additions & 1 deletion packages/carousel/src/Carousel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,18 @@ export const Carousel = ({
displayArrowsMobile,
buttonSize = '60px',
showArrowsOnHover = false,
overflowAllowancePxX = 0,
overflowAllowancePxY = 0,
overflowAllowancePxTop = 0,
maxHeight,
}) => {
const widths = layoutToFlexWidths(layout, children.length)
const layoutSize = layout?.split('-').length
const visibleSlidesArray = getVisibleSlidesArray(visibleSlides)
const { responsiveVisibleSlides, browserWidth } = useResponsiveVisibleSlides(visibleSlidesArray)
const overflowAdjust = overflowAllowancePxTop
? (overflowAllowancePxTop + overflowAllowancePxY) / 2
: overflowAllowancePxY

if (!displayArrowsMobile && browserWidth < CAROUSEL_BREAKPOINT_1) {
return (
Expand All @@ -78,14 +85,22 @@ export const Carousel = ({
onSlideChange={onSlideChange}
visibleSlides={mobileVisibleSlides || getMobileVisibleSlides(visibleSlides)}
currentSlideOverride={currentSlide}
overflowAllowancePxX={overflowAllowancePxX}
overflowAllowancePxY={overflowAllowancePxY}
overflowAllowancePxTop={overflowAllowancePxTop}
>
{React.Children.map(children, (item) => item)}
</SlideBox>
)
}

return (
<CarouselWrapper>
<CarouselWrapper
overflowAllowancePxX={overflowAllowancePxX}
overflowAllowancePxY={overflowAllowancePxY}
overflowAllowancePxTop={overflowAllowancePxTop}
maxHeight={maxHeight}
>
<CarouselProvider
naturalSlideWidth={naturalSlideWidth}
naturalSlideHeight={naturalSlideHeight}
Expand Down Expand Up @@ -125,6 +140,7 @@ export const Carousel = ({
})
) : (
<ArrowButton
overflowAdjust={overflowAdjust}
ml={sideButtonMargin}
pl={slideSpacing}
type='prev'
Expand Down Expand Up @@ -172,6 +188,7 @@ export const Carousel = ({
})
) : (
<ArrowButton
overflowAdjust={overflowAdjust}
mr={sideButtonMargin}
pr={slideSpacing}
type='next'
Expand Down Expand Up @@ -251,4 +268,12 @@ Carousel.propTypes = {
buttonSize: PropTypes.string,
/** When arrow position is side, hide arrows and shows when hovers on carousel */
showArrowsOnHover: PropTypes.bool,
/** Number of px to allow overflow on top and bottom of Carousel to display things like shadows */
overflowAllowancePxY: PropTypes.number,
/** Number of px to allow overflow on left and right to display things like shadows */
overflowAllowancePxX: PropTypes.number,
/** Number of px to allow oveflow on top (will override the overflowAllowancePxY value for top) */
overflowAllowancePxTop: PropTypes.number,
/** Number of px to set maxHeight to counteract large overflow values*/
maxHeight: PropTypes.number,
}
11 changes: 10 additions & 1 deletion packages/carousel/src/Carousel.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ describe('Carousel', () => {
onSlideChange={onSlideChange}
onSlideClick={onSlideClick}
onSlideKeyDown={onSlideKeyDown}
overflowAllowancePxX={20}
overflowAllowancePxY={40}
>
<Flex>Slide 1</Flex>
<Flex>Slide 2</Flex>
Expand Down Expand Up @@ -75,7 +77,14 @@ describe('Carousel', () => {
it('Should NOT render SlideBox for mobile sizes with displayArrowsMobile = true', () => {
window.innerWidth = 720
const { queryByTestId } = render(
<Carousel displayArrowsMobile layout='50-50' arrowsPosition='bottom' currentSlide={1}>
<Carousel
displayArrowsMobile
layout='50-50'
arrowsPosition='bottom'
currentSlide={1}
overflowAllowancePxTop={10}
maxHeight={220}
>
<Flex>Slide 1</Flex>
<Flex>Slide 2</Flex>
<Flex>Slide 3</Flex>
Expand Down
109 changes: 108 additions & 1 deletion packages/carousel/src/Carousel.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import React from 'react'
import PropTypes from 'prop-types'
import { within } from '@storybook/testing-library'
import { expect } from '@storybook/jest'
import { Flex, Card, Container, Image, Text, Box, BackgroundImage } from 'pcln-design-system'
import { Flex, Card, Container, Image, Text, Box, BackgroundImage, Relative } from 'pcln-design-system'
import Popover from 'pcln-popover'
import styled from 'styled-components'
import { action } from '@storybook/addon-actions'
import { Carousel } from './Carousel'
Expand Down Expand Up @@ -131,6 +132,112 @@ Basic.play = async ({ canvasElement }) => {
expect(canvas.queryByTestId('slide-box')).not.toBeInTheDocument()
}

const SimpleTextContent = () => (
<Text textAlign='center' py={5}>
Popover!
</Text>
)

const CardWithPopover = () => {
return (
<Card borderRadius={20} boxShadowSize='lg' borderWidth={0} p={4} height='200px' bg='background.lightest'>
<Popover
renderContent={SimpleTextContent}
ariaLabel='Test Popover'
idx={1}
width={150}
isOpen={false}
openOnHover
placement='top'
>
<Box>Hover for Popover</Box>
</Popover>
</Card>
)
}
//Overflow Template
function renderOverflowCards() {
return Array.from(Array(SLIDE_COUNT)).map((_, idx) => <CardWithPopover key={idx} />)
}

const OverflowTemplate = (args) => (
<Box>
<Relative
width={1}
bg='background.light'
zIndex={2}
height='80px'
borderRadius='xl'
mb={[3, 3, 3, 4]}
mx={2}
>
Above
</Relative>
<Carousel {...args}>{renderOverflowCards()}</Carousel>
<Relative
width={1}
bg='background.light'
zIndex={3}
height='80px'
borderRadius='xl'
mt={[3, 3, 3, 4]}
mx={2}
>
Below
</Relative>
</Box>
)

export const OverflowAllowed = OverflowTemplate.bind({})
OverflowAllowed.args = {
visibleSlides: 3,
mobileVisibleSlides: [1.1, 2.1, 2.1],
showDots: false,
showForwardBackBtns: true,
arrowPositions: 'bottom',
onSlideChange: action('Slide Change'),
buttonSize: '60px',
sideButtonMargin: '-30px',
overflowAllowancePxX: 46,
overflowAllowancePxY: 20,
overflowAllowancePxTop: 2,
maxHeight: 220,
}

//Overflow With backround
const OverflowBackgroundTemplate = (args) => (
<Box>
<Relative width={1} bg='background.light' zIndex={2} height='80px' borderRadius='xl'>
Above
</Relative>

<Relative zIndex={2} bg='primary.light' px={2} py={2} borderRadius='xl' my={4}>
<Carousel {...args}>{renderOverflowCards()}</Carousel>
</Relative>

<Relative width={1} bg='background.light' zIndex={3} height='80px' borderRadius='xl'>
Below
</Relative>
</Box>
)

export const OverflowBackground = OverflowBackgroundTemplate.bind({})
OverflowBackground.args = {
visibleSlides: 3.1,
mobileVisibleSlides: [1.1, 2.1, 2.1],
showDots: false,
showForwardBackBtns: true,
arrowPositions: 'bottom',
onSlideChange: action('Slide Change'),
buttonSize: '60px',
sideButtonMargin: '-30px',
overflowAllowancePxX: 8,
overflowAllowancePxY: 20,
overflowAllowancePxTop: 2,
maxHeight: 220,
}

//Show Arrows On Hover
export const ShowArrowsOnHover = BasicTemplate.bind({})
ShowArrowsOnHover.args = {
visibleSlides: 3.15,
Expand Down
24 changes: 24 additions & 0 deletions packages/carousel/src/Carousel.styles.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import styled from 'styled-components'

export const CarouselWrapper = styled.div`
${({ maxHeight }) => (maxHeight ? `max-height: ${maxHeight}px;` : '')}
.buttonBack___1mlaL,
.buttonFirst___2rhFr,
.buttonLast___2yuh0,
Expand Down Expand Up @@ -110,6 +111,29 @@ export const CarouselWrapper = styled.div`
.horizontalSlider___281Ls {
position: relative;
overflow: hidden;
${({ overflowAllowancePxX }) =>
overflowAllowancePxX
? `
padding-left: ${overflowAllowancePxX}px;
margin-left: -${overflowAllowancePxX}px;
padding-right: ${overflowAllowancePxX}px;
margin-right: -${overflowAllowancePxX}px;
`
: ''}
${({ overflowAllowancePxY, overflowAllowancePxTop }) =>
overflowAllowancePxY || overflowAllowancePxTop
? `
padding-top: ${overflowAllowancePxTop || overflowAllowancePxY}px;
transform: translateY(-${overflowAllowancePxTop || overflowAllowancePxY}px);
`
: ''}
${({ overflowAllowancePxY }) =>
overflowAllowancePxY
? `
padding-bottom: ${overflowAllowancePxY}px;
margin-bottom: -${overflowAllowancePxY}px;
`
: ''}
}
[dir='rtl'] .horizontalSlider___281Ls {
direction: ltr;
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/SlideBox/Slide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type SlideProps = BoxProps & {
isCurrentSlide: boolean
numSlides: number
slideBoxRef: React.RefObject<HTMLDivElement>
overflowAllowancePxX?: number
}

export function Slide({
Expand All @@ -24,6 +25,7 @@ export function Slide({
width,
numSlides,
slideBoxRef,
overflowAllowancePxX,
}: SlideProps): JSX.Element {
const ref = useRef()

Expand All @@ -32,7 +34,7 @@ export function Slide({
if (isCurrentSlide === true && typeof slideBoxRef?.current?.scroll === 'function' && ref?.current) {
const { offsetLeft, offsetParent, offsetWidth } = ref.current
const { offsetWidth: parentOffset } = offsetParent || {}
slideBoxRef?.current?.scroll({ left: offsetLeft - parentOffset + offsetWidth })
slideBoxRef?.current?.scroll({ left: offsetLeft - parentOffset + offsetWidth + overflowAllowancePxX })
}
}, [isCurrentSlide, ref])

Expand Down
10 changes: 9 additions & 1 deletion packages/core/src/SlideBox/SlideBox.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ describe('SlideBox', () => {
slideSpacing={2}
currentSlideOverride={2}
arrowPosition='side'
overflowAllowancePxX={20}
overflowAllowancePxY={40}
>
<Box key='testkey'>1</Box>
<Box>2</Box>
Expand All @@ -39,7 +41,13 @@ describe('SlideBox', () => {
const slideChange = jest.fn()

const { getByTestId } = render(
<SlideBox visibleSlides={1} onSlideChange={slideChange} slideSpacing={2} arrowPosition='bottom'>
<SlideBox
visibleSlides={1}
onSlideChange={slideChange}
slideSpacing={2}
arrowPosition='bottom'
overflowAllowancePxTop={10}
>
<Box>1</Box>
<Box>2</Box>
<Box>3</Box>
Expand Down
Loading

0 comments on commit 7f1b6e7

Please sign in to comment.