Skip to content

Add variableHeight argument to CarouselProvider that disables the ratio #243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ Any remaining props not consumed by the component are passed directly to the roo
| dragEnabled | boolean | true | No | Set to true to enable mouse dragging events |
| visibleSlides | number | 1 | No | The number of slides to show at once. This number should be <= totalSlides |
| infinite | boolean | false | No | Should the carousel continue or stop at the beginning or end of the slides |
| isIntrinsicHeight | boolean | false | No | Disables the enforced height ratio, and instead uses the intrinsic height of the slides. This option can only be active in horizontal orientation, it will throw an error in vertical orientation. |

#### The CarouselProvider component creates the following pseudo HTML by default:

Expand Down
10 changes: 10 additions & 0 deletions src/App/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Example10,
Example11,
Example12,
Example13,
} from './examples';
import s from './style.scss';

Expand Down Expand Up @@ -149,6 +150,7 @@ class DevelopmentApp extends React.Component {
<option value="10">Carousel with custom spinner component.</option>
<option value="11">Simple carousel with event callbacks on Slider.</option>
<option value="12">Infinite Carousel</option>
<option value="13">Using Intrinsic Axis Dimension</option>
</select>
</label>
</p>
Expand Down Expand Up @@ -237,6 +239,14 @@ class DevelopmentApp extends React.Component {
<Example12 />
</section>
)}

{(value === '0' || value === '13') && (
<section id="example--13">
<hr />
<Example13 />
</section>
)}

</div>
</div>
</div>
Expand Down
84 changes: 84 additions & 0 deletions src/App/examples/Example13/Example13.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react';
import {
ButtonBack, ButtonFirst, ButtonLast, ButtonNext, CarouselProvider, Slide, Slider,
} from '../../..';

import s from '../../style.scss';

export default () => (
<CarouselProvider
visibleSlides={2}
totalSlides={4}
step={1}
naturalSlideWidth={400}
naturalSlideHeight={500}
isIntrinsicHeight
>
<h2 className={s.headline}>With intrinsic axis dimension</h2>
<p />
<Slider className={s.slider}>
<Slide index={0}>
<h1>This is a test slide to demonstrate, how this affects height</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing
elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</Slide>
<Slide index={1}>
<h1>This is a test slide to demonstrate, how this affects height</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et
accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing
elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
<h1>This is a test slide to demonstrate, how this affects height</h1>
<p>
lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. at vero eos et
accusam et justo duo dolores et ea rebum. stet clita kasd gubergren, no sea takimata
sanctus est lorem ipsum dolor sit amet. lorem ipsum dolor sit amet, consetetur sadipscing
elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. at vero eos et accusam et justo duo dolores et ea rebum. stet clita
kasd gubergren, no sea takimata sanctus est lorem ipsum dolor sit amet.
</p>
</Slide>
<Slide index={2}>
<h1>This is a test slide to demonstrate, how this affects height</h1>
<p>
lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. at vero eos et
accusam et justo duo dolores et ea rebum. stet clita kasd gubergren, no sea takimata
sanctus est lorem ipsum dolor sit amet. lorem ipsum dolor sit amet, consetetur sadipscing
elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. at vero eos et accusam et justo duo dolores et ea rebum. stet clita
kasd gubergren, no sea takimata sanctus est lorem ipsum dolor sit amet.
</p>
</Slide>
<Slide index={2}>
<h1>This is a test slide to demonstrate, how this affects height</h1>
<p>
lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. at vero eos et
accusam et justo duo dolores et ea rebum. stet clita kasd gubergren, no sea takimata
sanctus est lorem ipsum dolor sit amet. lorem ipsum dolor sit amet, consetetur sadipscing
elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. at vero eos et accusam et justo duo dolores et ea rebum. stet clita
kasd gubergren, no sea takimata sanctus est lorem ipsum dolor sit amet.
</p>
</Slide>
</Slider>
<ButtonFirst>First</ButtonFirst>
<ButtonBack>Back</ButtonBack>
<ButtonNext>Next</ButtonNext>
<ButtonLast>Last</ButtonLast>
</CarouselProvider>
);
3 changes: 3 additions & 0 deletions src/App/examples/Example13/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Example13 from './Example13';

export default Example13;
1 change: 1 addition & 0 deletions src/App/examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export { default as Example9 } from './Example9';
export { default as Example10 } from './Example10';
export { default as Example11 } from './Example11';
export { default as Example12 } from './Example12';
export { default as Example13 } from './Example13';
7 changes: 7 additions & 0 deletions src/CarouselProvider/CarouselProvider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const CarouselProvider = class CarouselProvider extends React.Component {
dragEnabled: PropTypes.bool,
visibleSlides: PropTypes.number,
infinite: PropTypes.bool,
isIntrinsicHeight: PropTypes.bool,
};

static defaultProps = {
Expand All @@ -51,10 +52,14 @@ const CarouselProvider = class CarouselProvider extends React.Component {
dragEnabled: true,
visibleSlides: 1,
infinite: false,
isIntrinsicHeight: false,
};

constructor(props) {
super(props);
if (props.isIntrinsicHeight && props.orientation !== 'horizontal') {
throw Error('isIntrinsicHeight can only be used in "horizontal" orientation. See Readme for more information.');
}
const options = {
currentSlide: props.currentSlide,
disableAnimation: props.disableAnimation,
Expand All @@ -81,6 +86,7 @@ const CarouselProvider = class CarouselProvider extends React.Component {
dragEnabled: props.dragEnabled,
visibleSlides: props.visibleSlides,
infinite: props.infinite,
isIntrinsicHeight: props.isIntrinsicHeight,
};
this.carouselStore = new Store(options);
}
Expand Down Expand Up @@ -179,6 +185,7 @@ const CarouselProvider = class CarouselProvider extends React.Component {
dragEnabled,
visibleSlides,
infinite,
isIntrinsicHeight,
...filteredProps
} = this.props;

Expand Down
15 changes: 15 additions & 0 deletions src/CarouselProvider/__tests__/CarouselProvider.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,19 @@ describe('<CarouselProvider />', () => {
false,
);
});
it('should correctly set store variable when using isIntrinsicHeight', async () => {
const wrapper = mount(
<CarouselProvider {...props} isIntrinsicHeight>
test
</CarouselProvider>,
);
expect(wrapper.instance().getStore().state.isIntrinsicHeight).toBe(true);
});
it('should throw an error, when tryng to use isIntrinsicHeight in vertical orientation', async () => {
expect(() => shallow(
<CarouselProvider {...props} isIntrinsicHeight orientation="vertical">
test
</CarouselProvider>,
)).toThrow(Error);
});
});
16 changes: 16 additions & 0 deletions src/Slide/Slide.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const Slide = class Slide extends React.PureComponent {
tag: PropTypes.string,
totalSlides: PropTypes.number.isRequired,
visibleSlides: PropTypes.number.isRequired,
isIntrinsicHeight: PropTypes.bool,
}

static defaultProps = {
Expand All @@ -40,6 +41,7 @@ const Slide = class Slide extends React.PureComponent {
style: {},
tabIndex: null,
tag: 'li',
isIntrinsicHeight: false,
}

constructor(props) {
Expand Down Expand Up @@ -103,6 +105,7 @@ const Slide = class Slide extends React.PureComponent {
tag: Tag,
totalSlides,
visibleSlides,
isIntrinsicHeight,
...props
} = this.props;

Expand All @@ -116,6 +119,18 @@ const Slide = class Slide extends React.PureComponent {
tempStyle.paddingBottom = pct((naturalSlideHeight * 100) / naturalSlideWidth);
}

const innerStyle = {};
if (isIntrinsicHeight) {
if (orientation === 'horizontal') {
tempStyle.height = 'unset';
} else {
tempStyle.width = 'unset';
}
tempStyle.position = 'unset';
tempStyle.paddingBottom = 'unset';
innerStyle.position = 'unset';
}

const newStyle = Object.assign({}, tempStyle, style);

const isVisible = this.isVisible();
Expand Down Expand Up @@ -156,6 +171,7 @@ const Slide = class Slide extends React.PureComponent {
<InnerTag
ref={(el) => { this.innerTagRef = el; }}
className={newInnerClassName}
style={innerStyle}
>
{this.props.children}
{this.renderFocusRing()}
Expand Down
24 changes: 24 additions & 0 deletions src/Slide/__tests__/Slide.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,28 @@ describe('<Slide />', () => {
const wrapper = shallow(<Slide {...props} tabIndex={7} />);
expect(wrapper.find('.slide').prop('tabIndex')).toBe(7);
});
it('should correctly set styles, if isIntrinsicHeight is set', () => {
// this is for testing only.
// eslint-disable-next-line jsx-a11y/tabindex-no-positive
const wrapper = shallow(<Slide {...props} isIntrinsicHeight />);
const slideStyle = wrapper.find('.slide').prop('style');
expect(slideStyle.paddingBottom).toBe('unset');
expect(slideStyle.height).toBe('unset');
expect(slideStyle.position).toBe('unset');

const innerSlideStyle = wrapper.find('.carousel__inner-slide').prop('style');
expect(innerSlideStyle.position).toBe('unset');
});
it('should correctly set styles, in vertical mode if isIntrinsicHeight is set', () => {
// this is for testing only.
// eslint-disable-next-line jsx-a11y/tabindex-no-positive
const wrapper = shallow(<Slide {...props} orientation="vertical" isIntrinsicHeight />);
const slideStyle = wrapper.find('.slide').prop('style');
expect(slideStyle.paddingBottom).toBe('unset');
expect(slideStyle.width).toBe('unset');
expect(slideStyle.position).toBe('unset');

const innerSlideStyle = wrapper.find('.carousel__inner-slide').prop('style');
expect(innerSlideStyle.position).toBe('unset');
});
});
1 change: 1 addition & 0 deletions src/Slide/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export default WithStore(Slide, state => ({
slideSize: state.slideSize,
totalSlides: state.totalSlides,
visibleSlides: state.visibleSlides,
isIntrinsicHeight: state.isIntrinsicHeight,
}));
10 changes: 10 additions & 0 deletions src/Slider/Slider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const Slider = class Slider extends React.Component {
}),
trayTag: PropTypes.string,
visibleSlides: PropTypes.number,
isIntrinsicHeight: PropTypes.bool,
}

static defaultProps = {
Expand All @@ -75,6 +76,7 @@ const Slider = class Slider extends React.Component {
trayProps: {},
trayTag: 'ul',
visibleSlides: 1,
isIntrinsicHeight: false,
}

static slideSizeInPx(orientation, sliderTrayWidth, sliderTrayHeight, totalSlides) {
Expand Down Expand Up @@ -554,6 +556,7 @@ const Slider = class Slider extends React.Component {
trayProps,
trayTag: TrayTag,
visibleSlides,
isIntrinsicHeight,
...props
} = this.props;

Expand All @@ -579,12 +582,19 @@ const Slider = class Slider extends React.Component {
trayStyle.transition = 'none';
}

if (isIntrinsicHeight) {
trayStyle.display = 'flex';
trayStyle.alignItems = 'stretch';
}

if (orientation === 'vertical') {
trayStyle.transform = `translateY(${trans}) translateY(${this.state.deltaY}px)`;
trayStyle.width = pct(100);
trayStyle.flexDirection = 'column';
} else {
trayStyle.width = pct(slideTraySize);
trayStyle.transform = `translateX(${trans}) translateX(${this.state.deltaX}px)`;
trayStyle.flexDirection = 'row';
}

const sliderClasses = cn([
Expand Down
6 changes: 6 additions & 0 deletions src/Slider/__tests__/Slider.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -1055,5 +1055,11 @@ describe('<Slider />', () => {
expect(divProps.step).toBeUndefined();
expect(divProps.infinite).toBeUndefined();
});
it('should correctly set styles, if isIntrinsicHeight is set', () => {
const wrapper = shallow(<Slider {...props} orientation="vertical" isIntrinsicHeight />);
const sliderStyle = wrapper.find('.sliderTray').prop('style');
expect(sliderStyle.display).toBe('flex');
expect(sliderStyle.alignItems).toBe('stretch');
});
});
});
1 change: 1 addition & 0 deletions src/Slider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export default WithStore(Slider, state => ({
totalSlides: state.totalSlides,
touchEnabled: state.touchEnabled,
visibleSlides: state.visibleSlides,
isIntrinsicHeight: state.isIntrinsicHeight,
}));
2 changes: 2 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ interface CarouselState {
readonly dragEnabled: boolean
readonly visibleSlides: number
readonly infinite: boolean
readonly isIntrinsicHeight: boolean
}

interface CarouselStoreInterface {
Expand Down Expand Up @@ -92,6 +93,7 @@ interface CarouselProviderProps {
readonly dragEnabled?: CarouselState['dragEnabled']
readonly visibleSlides?: CarouselState['visibleSlides']
readonly infinite?: CarouselState['infinite']
readonly isIntrinsicHeight?: CarouselState['isIntrinsicHeight']
}

type CarouselProviderInterface = React.ComponentClass<CarouselProviderProps>
Expand Down