A React component that endeavors to provide flexbility for customizing carousel/slider.
carr1005.github.io/react-carousel-slider/index.html
Install it from npm.
npm install react-carousel-slider
As ES module:
import CarouselSlider from "react-carousel-slider"
As CommonJS module:
var CarouselSlider = require("react-carousel-slider")
The UMD build:
<script src="https://unpkg.com/react-carousel-slider/umd/react-carousel-slider.js"></script>
Touch events would be rigistered on this component automatically when mobile device viewport is detected, so the drag event is also available on mobile.
We could render a component with the slideItems
prop which accepts an array of objects with the specific simple sturcture and keys in default style. If the slider doesn't show the image when you are testing with local images, make sure if you do it in the right way.
import React, {Component} from 'react'
import CarouselSlider from 'react-carousel-slider';
class App extends Component {
render() {
let data = [
{
des: "1",
imgSrc: "https://i.imqur.com/yourImage.jpg"
},
{
des: "2",
imgSrc: "https://i.imqur.com/yourImage2.jpg"
}
];
return <CarouselSlider slideItems = {data} />;
}
}
Or give an array of your own regular React elements to slideCpnts
prop, this lets our slide have availability to contain a clickable link. Even cooperating with <Link>
component of React Router library for client side routing is possible.
import React, {Component} from 'react'
import CarouselSlider from 'react-carousel-slider';
import {BrowserRouter as Router, Link } from 'react-router-dom';
class App extends Component {
render() {
let jsonData = require('./slidesExample.json');
/*
{
"items": [
{
"des": "1",
"imgSrc": "https://i.imqur.com/yourImage.jpg"
},
{
"des": "2",
"imgSrc": "https://i.imqur.com/yourImage2.jpg"
}
]
}
*/
let items = jsonData.items.map((item, index) =>
<Link to = {'/' + item.des} >
<img src = {item.imgSrc} ></img>
<p>{item.des}</p>
</Link>
);
return (<Router>
<CarouselSlider slideCpnts = {items} />
</Router>);
}
}
All props below are optional, default setting is applied if we don't specify ours.
The Key without prefixng a * is pure css property, what be filled in column Value are just recommended because of the anticipated purpose, feel free to try if things are under control.
[
{
des: "1",
imgSrc: "https://i.imqur.com/yourImage.jpg"
},
{
des: "2",
imgSrc: "https://i.imqur.com/yourImage2.jpg"
}
]
slideCpnts
- accepts an array of regular React elements, the<img></img>
element and available image source are required, we have the default style for<p>
block, override it by specifying your own with using inline-styles.
let textBoxStyle = {
width: "50%",
background: "transparent",
textAlign: "right",
color: "black"
};
let items = jsonData.items.map((item, index) =>
<div>
<img src = {item.imgSrc} ></img>
<p style = {textBoxStyle} >{item.des}</p>
</div>
);
Key | Value | Default | Description & Notice |
---|---|---|---|
* autoSliding | {interval: "?s" } |
false |
Interval between sliding, suffix 's'(seconds) is required, only giving true is ineffectual. |
* circular | true | false |
true |
|
* duration | "?s" |
"0.5s" |
Key | Value | Default | Description & Notice |
---|---|---|---|
* button | true | false |
true |
You may want to set it to false insome situations, e.g., in mobile device viewport. |
* dots | true | false |
true |
|
* flag | true | false |
false |
dotsSetting
- accepts an object, this prop would be ignored if corresponding value ofdots
is set tofalse
in propaccEle
.
Key | Value | Default | Description & Notice |
---|---|---|---|
* placeOn | top | bottom | beneath |
Only options in column Value are available, fine-tune the position with margin- property in style below. |
|
* style | {} |
Available keys and expected values in object which dotsSetting.style
accepts.
Key | Value | Default | Description & Notice |
---|---|---|---|
* dotSpace | <length> |
"5px" |
Space between dots. |
* dotSize | <length> |
"10px" |
For width and height of dot. |
* dotColor | rgb() | rgba() | hex value |
"#dbdbdb" |
|
* currDotSize | <length> |
"12px" |
For width and height of current dot. |
* currDotColor | rgb() | rgba() | hex value |
"#3897f0" |
|
* marginTop | <length> |
"15px" |
To fine-tune the vertical position when placeOn is set to top . |
* marginBottom | <length> |
"15px" |
To fine-tune the vertical position when placeOn is set to bottom . |
buttonSetting
- accepts an object, this prop would be ignored if corresponding value ofbutton
is set tofalse
in propaccEle
. We usecontent: '\003c'
,content: '\003e'
to present buttons, you may want to design your own by utilizing propslBtnCpnt
andrBtnCpnt
.
Key | Value | Default | Description & Notice |
---|---|---|---|
* placeOn | top-left | top-right | middle-inside | middle-outside | bottom-left | bottom-right | bottom-beneath |
"top-left" |
Only options in column Value are available, fine-tune the position with margin property in style.left / style.right .Notice about option middle-outside :- If your sliderBox width is narrow, maybe you neet parent element like: <div style={{ width: "?px", margin: "0 auto", position: "relative" }}> </div> to confine the absolute positioned button.- This option would not function with hoverEvent property below. |
* hoverEvent | true | false |
false |
Buttons are only visible when the cursor hover on the slider. |
* style | {left: {}, right: {}} |
Recommended keys and values in object which buttonSetting.style.left
or buttonSetting.style.right
accepts.
Key | Value | Default | Description & Notice |
---|---|---|---|
color | hex value | "#ffffff" |
|
background | rgb() | rgba() | hex value |
"#757575" |
|
height | <length> |
"30px" |
|
width | <length> |
"30px" |
|
margin | <length> |
"10px" |
|
fontSize | <length> |
"20px" |
|
borderRadius | <length> | <percentage> |
"2px" |
|
border | All border property | "none" |
lBtnCpnt
,rBtnCpnt
- Both accepts a regular React element. Use these props to give our own designed button,style
property inbuttonSetting
would be ignored. See the example in Demo.
Key | Value | Default | Description & Notice |
---|---|---|---|
height | <length> | <percentage> |
"400px" |
|
width | <length> | <percentage> |
"90%" |
|
background | rgb() | rgba() | hex value |
"#EEEEEE" |
|
border | All available properties | none |
Key | Value | Default | Description & Notice |
---|---|---|---|
height | <length> | <percentage> |
"80%" |
|
padding | <length> | <percentage> |
"3px" |
|
background | rgb() | rgba() | hex value |
"#EEEEEE" |
|
margin | 0px ?px |
"0px 40px" |
To give the space between slides , only accept value in form 0px ?px now. |
minWidth | <length> | <percentage> |
100px |
For the situation that the source of image is not provided, and maybe you want to let your slide still have room. See more explaination in the Demo. |
Key | Value | Default | Description & Notice |
---|---|---|---|
color | hex value | "#ffffff" |
|
padding | <length> | <percentage> |
"10px" |
|
background | rgb() | rgba() | hex value |
"rgba(117, 117, 117, .6)" |
|
borderRadius | <length> | <percentage> |
"2px" |
|
textAlign | left | right | center |
"center" |
|
width | <length> | <percentage> |
"75%" |
|
top | <length> | <percentage> |
"80%" |
To adjust vertical position.50% for centering. |
fontSize | <length> |
||
fontWeight | All available properties |
While testing this component with local images, some problems may appear because we are just new to develop in React with webpack.
If we have a directory structure like:
- app
|___ demo
| |___ images
| | |___ yourImage1.jpg
| | |___ yourImage2.jpg
| |
| |___index.js
|
|
|___ src
|
...
In /app/demo/index.js
, provide image sources with relative paths such as:
let data = [
{
des: "1",
imgSrc: "./images/yourImage1.jpg"
},
{
des: "2",
imgSrc: "./images/yourImage2.jpg"
}
];
return <CarouselSlider slideItems = {data} />;
The images certainly won't be rendered. This is not caused by the practice in our component, it caused by the bundling mechanism that webpack works. We could have more tests:
let data = [
{
des: "1",
imgSrc: "./images/yourImage1.jpg"
},
{
des: "2",
imgSrc: "./images/yourImage2.jpg"
}
];
let imgOne = (<img src = {data[0].imgSrc}></img>);
let imgTwo = (<img src = {require(data[0].imgSrc)}></img>);
return (<div>
{imgOne}
{imgTwo}
</div>);
Neither of image elements above can load and render the image succesfully.
Here are some points that we need to know:
-
Webpack needs to know what files to bundle at compile time, but dynamic image path in expression would only know in runtime.
-
In fact, there is a tricky way that gives concatenated string containing expression to
require()
to include the images for bundling. But to properly render the images, it still need to do something onloaders
inwebpack.config.js
. We are not going this way in this component behind. -
To get the proper image sources from local and pass to our carousel slider component, here is a good way with reqiure.context:
/* In the directory structure we assume above*/
let data = [
{
des: "1",
imgSrc: "yourImage1.jpg"
},
{
des: "2",
imgSrc: "yourImage2.jpg"
}
];
let assetsPath = require.context('./images', false, /\.(png|jpe?g|svg)$/);
// Substituting the imgSrc from file name in ./images to their corresponding path after they are bundled.
data.map((item, index) => {
// console.log(assetsPath.keys(), assetsPath.id);
item.imgSrc = assetsPath('./' + item.imgSrc);
});
return <CarouselSlider slideItems = {data} />;
MIT Licensed. Copyright (c) Carr.W 2018.