Skip to content

Commit

Permalink
Merge ba629c5 into 1581799
Browse files Browse the repository at this point in the history
  • Loading branch information
victorhmp committed Aug 2, 2019
2 parents 1581799 + ba629c5 commit d4c875e
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 21 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,26 +7,38 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- Support for `minPerPage` prop to be passed to the Slider and Dots components.

## [0.5.8] - 2019-07-09

### Fixed

- Prevent slides from stretching (and center them) if the total number of items is smaller than the number of items visible per page.

## [0.5.7] - 2019-07-08

### Fixed

- Issue where the slider would flicker if autoplay delay was 0.

## [0.5.6] - 2019-07-04

### Fixed

- Infer slide size on SSR, to prevent flickering on hydration.

## [0.5.5] - 2019-07-01

### Fixed

- Fixes issue with SSR hydration when the quantity of items is smaller than the number of items per page.

## [0.5.4] - 2019-06-27

### Fixed

- Build assets with new builder hub.

## [0.5.3] - 2019-04-12
Expand Down
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -186,6 +186,7 @@ render() {
| `loop` | `bool` | :no_entry_sign: | `false` | If the slides should be looping |
| `onChangeSlide` | `func` | :heavy_check_mark: | :no_entry_sign: | Function to change the value of currentSlide. The function should expect a `number` as it's only parameter |
| `perPage` | `number/object` | :no_entry_sign: | `1` | Amount of slides to be on the screen, if a number is passed, then that's the number of slides that will be shown, if an object with breakpoints is passed, then the component will check the size of the screen to see how many slides will be on the screen at the same time |
| `minPerPage` | `number` | :no_entry_sign: | `1` | Minimum amount of slides to be on the screen, can be used to control how many itens will be displayed in the smallest screen size |
| `resizeDebounce` | `number` | :no_entry_sign: | `250` | Resize debounce timer in milliseconds |
| `rootTag` | `string` | :no_entry_sign: | `'div'` | Tag to be rendered in the root of the slider |
| `sliderFrameTag` | `string` | :no_entry_sign: | `'ul'` | Tag to be rendered in the slider frame element |
Expand Down Expand Up @@ -229,6 +230,7 @@ render() {
| `resizeDebounce` | `number` | :no_entry_sign: | `250` | Debounce time in milliseconds |
| `rootTag` | `string` | :no_entry_sign: | `'ul'` | Tag to be rendered as the root element of the component |
| `totalSlides` | `number` | :heavy_check_mark: | :no_entry_sign: | Total value of sliders that will be rendered |
| `minPerPage` | `number` | :no_entry_sign: | `1` | This prop works the same way the `minPerPage` of `Slider` and this component should receive the same value of `Slider` |
| `showDotsPerPage` | `bool` | :no_entry_sign: | `false` | If this frag is true, then every dot represent a page of slides (e.g. if `perPage = 2` and you have 4 elements, then you have 2 dots), if false, then it will render one dot to each slide |

## Styles API
Expand Down
8 changes: 6 additions & 2 deletions react/__tests__/Utils.test.js
Expand Up @@ -26,10 +26,14 @@ describe('Util functions', () => {
expect(resolveSlidesNumber(5)).toEqual(5)

window.resizeTo(400, 1000)
expect(resolveSlidesNumber({ 400: 2, 1000: 3 })).toEqual(2)
expect(resolveSlidesNumber(1, { 400: 2, 1000: 3 })).toEqual(2)

window.resizeTo(1000, 1000)
expect(resolveSlidesNumber({ 400: 2, 1000: 3 })).toEqual(3)
expect(resolveSlidesNumber(1, { 400: 2, 1000: 3 })).toEqual(3)

// Testing for minimum values
window.resizeTo(320, 1000)
expect(resolveSlidesNumber(2, { 320: 1, 500: 2, 750: 3 })).toEqual(2)
})

it('should set style correctly', () => {
Expand Down
1 change: 1 addition & 0 deletions react/__tests__/__snapshots__/Dots.test.js.snap
Expand Up @@ -4,6 +4,7 @@ exports[`<Dots /> component should match snapshot 1`] = `
<DocumentFragment>
<ul
class="dotsContainer absolute ma0 pa0 dib list"
resizedebounce="250"
>
<li
class="dib "
Expand Down
16 changes: 9 additions & 7 deletions react/components/Dots.js
Expand Up @@ -16,6 +16,8 @@ class Dots extends PureComponent {
activeDot: PropTypes.string,
notActiveDot: PropTypes.string,
}),
/** Current slide on the screen, if you have perPage > 1, then the current slide is the most left slide on the screen */
currentSlide: PropTypes.number,
/** Extra props to be applied to the dot element */
dotProps: PropTypes.object,
/** The size of the dots, can be a number (in this case it will use px unit), or a string (you have to pass the number with the unit e.g '3rem') */
Expand All @@ -26,6 +28,8 @@ class Dots extends PureComponent {
loop: PropTypes.bool,
/** Function to change the currentSlide */
onChangeSlide: PropTypes.func.isRequired,
/** This prop works the same way the minPerPage of Slider and this component should receive the same value of Slider */
minPerPage: PropTypes.number,
/** This prop works the same way the perPage of Slider and this component should receive the same value of Slider */
perPage: PropTypes.oneOfType([PropTypes.number, PropTypes.object]),
/** Debounce time in milliseconds. */
Expand Down Expand Up @@ -92,8 +96,8 @@ class Dots extends PureComponent {
}

_setPerPageOnResize = () => {
const { perPage } = this.props
this.perPage = resolveSlidesNumber(perPage)
const { minPerPage, perPage } = this.props
this.perPage = resolveSlidesNumber(minPerPage, perPage)
this.forceUpdate()
}

Expand All @@ -103,13 +107,10 @@ class Dots extends PureComponent {
dotTag: DotTag,
classes: classesProp,
dotProps,
showDotsPerPage,
minPerPage,
perPage,
currentSlide,
onChangeSlide,
totalSlides,
dotSize,
resizeDebounce,
...otherProps
} = this.props

Expand All @@ -123,7 +124,7 @@ class Dots extends PureComponent {
}

if (!this.perPage) {
this.perPage = resolveSlidesNumber(perPage)
this.perPage = resolveSlidesNumber(minPerPage, perPage)
}

return (
Expand All @@ -141,6 +142,7 @@ class Dots extends PureComponent {
[classes.activeDot]: i === this.selectedDot,
[classes.notActiveDot]: i !== this.selectedDot,
})

return (
<DotTag
className={dotClasses}
Expand Down
25 changes: 20 additions & 5 deletions react/components/Slider.js
Expand Up @@ -51,6 +51,8 @@ class Slider extends PureComponent {
loop: PropTypes.bool,
/** Function to change the value of currentSlide */
onChangeSlide: PropTypes.func.isRequired,
/** Minimum amount of slides to be on the screen */
minPerPage: PropTypes.number,
/** Amount of slides to be on the screen, if a number is passed, then thats the slides that will be shown,
* if an object with breakpoints is passed, then the component will check the size of the screen to see how
* many elements will be on the screen
Expand All @@ -68,6 +70,7 @@ class Slider extends PureComponent {
scrollByPage: PropTypes.bool,
/** Render runtime context */
runtime: PropTypes.object,
draggable: PropTypes.bool,
}

static defaultProps = {
Expand Down Expand Up @@ -104,7 +107,11 @@ class Slider extends PureComponent {
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.currentSlide !== prevState.currentSlide) {
const { currentSlide, children } = nextProps
const perPage = resolveSlidesNumber(nextProps.perPage, nextProps.runtime)
const perPage = resolveSlidesNumber(
nextProps.minPerPage,
nextProps.perPage,
nextProps.runtime
)
const currentSlideIsClone =
currentSlide < perPage ||
currentSlide >= React.Children.count(children) + perPage
Expand Down Expand Up @@ -133,7 +140,11 @@ class Slider extends PureComponent {
this._sliderFrame = React.createRef()
this._sliderFrameWidth = 0
this.handleResize = debounce(this.fit, props.resizeDebounce)
this.perPage = resolveSlidesNumber(props.perPage, props.runtime)
this.perPage = resolveSlidesNumber(
props.minPerPage,
props.perPage,
props.runtime
)

this.state = {
firstRender: true,
Expand Down Expand Up @@ -192,7 +203,11 @@ class Slider extends PureComponent {

this.setSelectorWidth()
this.setInnerElements()
this.perPage = resolveSlidesNumber(this.props.perPage, this.props.runtime)
this.perPage = resolveSlidesNumber(
this.props.minPerPage,
this.props.perPage,
this.props.runtime
)
this._sliderFrameWidth = this._sliderFrame.current.getBoundingClientRect().width
}

Expand All @@ -213,8 +228,8 @@ class Slider extends PureComponent {
}

fit = () => {
const { perPage, currentSlide, onChangeSlide } = this.props
this.perPage = resolveSlidesNumber(perPage, this.props.runtime)
const { minPerPage, perPage, currentSlide, onChangeSlide } = this.props
this.perPage = resolveSlidesNumber(minPerPage, perPage, this.props.runtime)
const newCurrentSlide =
Math.floor(currentSlide / this.perPage) * this.perPage

Expand Down
15 changes: 8 additions & 7 deletions react/utils/resolveSlidesNumber.js
Expand Up @@ -5,16 +5,17 @@
* If you pass for example
* perPage = {
* 400: 2,
* 1000: 3
* 1000: 3
* }
*
*
* If the size of the window is something between 400px and 999px if will return 2,
* if it is 1000px or bigger, it will return 3, and if it is smaller than 400px it
* if it is 1000px or bigger, it will return 3, and if it is smaller than 400px it
* will return the default value; that is, 1.
* @param {number|object} perPage
* @param {number|object} perPage
* @param {number|undefined} minPerPage
*/
function resolveSlidesNumber(perPage, runtime) {
let result = 1
function resolveSlidesNumber(minPerPage, perPage, runtime) {
let result = minPerPage || 1
if (typeof perPage === 'number') {
result = perPage
} else if (typeof perPage === 'object') {
Expand All @@ -31,7 +32,7 @@ function resolveSlidesNumber(perPage, runtime) {
}
}
}
return result
return result < minPerPage ? minPerPage : result
}

export default resolveSlidesNumber

0 comments on commit d4c875e

Please sign in to comment.