Skip to content

Feature/passing though events to slider #145

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 6 commits into from
May 9, 2019
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
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ Let's make a simple carousel with three slides, a next button, and a back button
```JSX
import React from 'react';
import { CarouselProvider, Slider, Slide, ButtonBack, ButtonNext } from 'pure-react-carousel';
```
```

3. Using Webpack or Rollup? Does your Webpack config have a loader for "css" files? If so, import the css as well.

```JSX
import React from 'react';
import { CarouselProvider, Slider, Slide, ButtonBack, ButtonNext } from 'pure-react-carousel';
import 'pure-react-carousel/dist/react-carousel.es.css';
```
```

4. Put a CarouselProvider component in your code. This allows the other carousel components to communicate with each other. The only required properties are the orientation, naturalSlideWidth, and naturalSlideHeight. The naturalSlideWidth and naturalSlideHeight are used to create an aspect ratio for each slide. Since the carousel is responsive by default, it will stretch to fill in the width of it's parent container. The CarouselProvider must also have children. We'll add the children in the next step.

Expand Down Expand Up @@ -129,7 +129,7 @@ Let's make a simple carousel with three slides, a next button, and a back button
naturalSlideWidth={100}
naturalSlideHeight={125}
totalSlides={3}
>
>
<Slider>
<Slide index={0}>I am the first Slide.</Slide>
<Slide index={1}>I am the second Slide.</Slide>
Expand All @@ -144,9 +144,9 @@ Let's make a simple carousel with three slides, a next button, and a back button
```


That's it. You have a super basic Carousel.
That's it. You have a super basic Carousel.

There are other components you can add, like ButtonFirst, ButtonLast, an Image component, and even an ImageWithZoom component that zooms on mouse hover or finger tap.
There are other components you can add, like ButtonFirst, ButtonLast, an Image component, and even an ImageWithZoom component that zooms on mouse hover or finger tap.

Obviously, you can customize the heck out of the layout. If you need to bury your Slider component in 18 parent divs, go for it. It will still do it's job. Feel free to add the className property to any of the Components to further customize your carousel. Or, hook into the many BEM named default CSS class names built into the carousel components.

Expand Down Expand Up @@ -215,6 +215,7 @@ A Slider is a viewport that masks slides. The Slider component must wrap one or
| onMasterSpinner | [function&#124;null] | null | No | Optional callback function that is called when the Master Spinner is visible. Requires that &lt;CarouselProvider /> set hasMasterSpinner to true |
| spinner | function | null | No | Optional inline JSX (aka "render props") to render your own custom spinner. Example `() => <MyCustomSpinnerComponent />` If left blank, the default spinner is used. |
| style | object | {} | No | Optional css styles to add to the Slider. Note: internal css properties take precedence over any styles specified in the styles object |
| trayProps | object | {} | No | Any props you want to attach to the slider tray with the exception of className and style. The className prop is handled via classNameTray prop above. Style is used internally. Any event handlers like onMouseDown or others are called after any of our internal event handlers. |
| trayTag | string | 'ul' | No | The HTML tag to used for the tray (the thing that holds all the slides and moves the slides back and forth.) |

#### The Slider component creates the following pseudo HTML by default.
Expand Down Expand Up @@ -428,7 +429,7 @@ Use this HOC to pass CarouselProvider state properties as props to a component.
</CarouselProvider>
```

WithStore has two arguments:
WithStore has two arguments:

`WithStore([component], [mapstateToProps])`

Expand Down
58 changes: 34 additions & 24 deletions package-lock.json

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

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@
"rollup-plugin-commonjs": "^9.2.0",
"rollup-plugin-eslint": "^5.0.0",
"rollup-plugin-img": "^1.1.0",
"rollup-plugin-livereload": "^0.6.0",
"rollup-plugin-livereload": "^1.0.0",
"rollup-plugin-multi-entry": "^2.0.1",
"rollup-plugin-node-resolve": "^3.4.0",
"rollup-plugin-node-resolve": "^4.2.3",
"rollup-plugin-postcss": "^2.0.3",
"rollup-plugin-replace": "^2.1.0",
"rollup-plugin-serve": "^0.6.0",
"rollup-plugin-serve": "^1.0.1",
"rollup-plugin-uglify": "^6.0.0",
"rollup-plugin-uglify-es": "0.0.1",
"rollup-watch": "^4.3.1",
Expand Down
64 changes: 56 additions & 8 deletions src/Slider/Slider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const Slider = class Slider extends React.Component {
disableAnimation: PropTypes.bool,
disableKeyboard: PropTypes.bool,
dragEnabled: PropTypes.bool.isRequired,
dragStep: PropTypes.number,
hasMasterSpinner: PropTypes.bool.isRequired,
interval: PropTypes.number.isRequired,
isPageScrollLocked: PropTypes.bool.isRequired,
Expand All @@ -35,11 +36,11 @@ const Slider = class Slider extends React.Component {
slideTraySize: PropTypes.number.isRequired,
spinner: PropTypes.func,
step: PropTypes.number.isRequired,
dragStep: PropTypes.number,
style: PropTypes.object,
tabIndex: PropTypes.number,
totalSlides: PropTypes.number.isRequired,
touchEnabled: PropTypes.bool.isRequired,
trayProps: PropTypes.shape({}),
trayTag: PropTypes.string,
visibleSlides: PropTypes.number,
}
Expand All @@ -51,14 +52,15 @@ const Slider = class Slider extends React.Component {
classNameTrayWrap: null,
disableAnimation: false,
disableKeyboard: false,
dragStep: 1,
moveThreshold: 0.1,
onMasterSpinner: null,
spinner: null,
style: {},
tabIndex: null,
trayProps: {},
trayTag: 'ul',
visibleSlides: 1,
dragStep: 1,
}

static slideSizeInPx(orientation, sliderTrayWidth, sliderTrayHeight, totalSlides) {
Expand Down Expand Up @@ -91,6 +93,7 @@ const Slider = class Slider extends React.Component {
this.handleOnTouchStart = this.handleOnTouchStart.bind(this);
this.playBackward = this.playBackward.bind(this);
this.playForward = this.playForward.bind(this);
this.callCallback = this.callCallback.bind(this);

this.state = {
cancelNextClick: false,
Expand Down Expand Up @@ -214,14 +217,26 @@ const Slider = class Slider extends React.Component {
this.sliderTrayElement = el;
}

callCallback(propName, ev) {
const { trayProps } = this.props;
if (trayProps && typeof trayProps[propName] === 'function') {
ev.persist();
trayProps[propName](ev);
}
}

handleOnMouseDown(ev) {
if (!this.props.dragEnabled) return;
if (!this.props.dragEnabled) {
this.callCallback('onMouseDown', ev);
return;
}
ev.preventDefault();
this.onDragStart({
screenX: ev.screenX,
screenY: ev.screenY,
mouseDrag: true,
});
this.callCallback('onMouseDown', ev);
}

handleOnMouseMove(ev) {
Expand All @@ -238,14 +253,21 @@ const Slider = class Slider extends React.Component {
}

handleOnClickCapture(ev) {
if (!this.state.cancelNextClick) return;
if (!this.state.cancelNextClick) {
this.callCallback('onClickCapture', ev);
return;
}
ev.stopPropagation();
ev.preventDefault();
this.setState({ cancelNextClick: false });
this.callCallback('onClickCapture', ev);
}

handleOnTouchStart(ev) {
if (!this.props.touchEnabled) return;
if (!this.props.touchEnabled) {
this.callCallback('onTouchStart', ev);
return;
}

if (this.props.orientation === 'vertical') {
ev.preventDefault();
Expand All @@ -258,6 +280,7 @@ const Slider = class Slider extends React.Component {
screenY: touch.screenY,
touchDrag: true,
});
this.callCallback('onTouchStart', ev);
}

handleDocumentScroll() {
Expand All @@ -273,12 +296,16 @@ const Slider = class Slider extends React.Component {
if (
!this.props.touchEnabled
|| (this.props.lockOnWindowScroll && this.isDocumentScrolling)
) return;
) {
this.callCallback('onTouchMove', ev);
return;
}

window.cancelAnimationFrame.call(window, this.moveTimer);

const touch = ev.targetTouches[0];
this.onDragMove(touch.screenX, touch.screenY);
this.callCallback('onTouchMove', ev);
}

forward() {
Expand Down Expand Up @@ -418,12 +445,14 @@ const Slider = class Slider extends React.Component {
this.sliderElement.focus();
}

handleOnTouchEnd() {
handleOnTouchEnd(ev) {
this.endTouchMove();
this.callCallback('onTouchEnd', ev);
}

handleOnTouchCancel() {
handleOnTouchCancel(ev) {
this.endTouchMove();
this.callCallback('onTouchCancel', ev);
}

endTouchMove() {
Expand Down Expand Up @@ -484,6 +513,7 @@ const Slider = class Slider extends React.Component {
tabIndex,
totalSlides,
touchEnabled,
trayProps,
trayTag: TrayTag,
visibleSlides,
...props
Expand Down Expand Up @@ -550,6 +580,23 @@ const Slider = class Slider extends React.Component {
// remove `dragStep` and `step` from Slider div, since it isn't a valid html attribute
const { dragStep, step, ...rest } = props;

// filter out some tray props before passing them in. We will process event handlers in the
// trayProps object as callbacks to OUR event handlers. Ref is needed by us. Style and
// className are in the main props. Can't merge them into trayProps without causing a breaking
// change.
const {
className: ignoreClassName,
onClickCapture,
onMouseDown,
onTouchCancel,
onTouchEnd,
onTouchMove,
onTouchStart,
ref: ignoreRef,
style: ignoreStyle,
...filteredTrayProps
} = trayProps;

return (
<div
ref={(el) => { this.sliderElement = el; }}
Expand All @@ -572,6 +619,7 @@ const Slider = class Slider extends React.Component {
onTouchCancel={this.handleOnTouchCancel}
onMouseDown={this.handleOnMouseDown}
onClickCapture={this.handleOnClickCapture}
{...filteredTrayProps}
>
{children}
</TrayTag>
Expand Down
Loading