Skip to content

Commit e5099b6

Browse files
author
Florian Bernard
committed
Merge pull request #1 from webcom-components/stack
Stack
2 parents 18fe20d + 8abdbc1 commit e5099b6

File tree

11 files changed

+469
-98
lines changed

11 files changed

+469
-98
lines changed

README.md

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
# react-card-scroll
22
A React component to horizontally navigate between components of same width (Bootstrap cards for example).
3-
It is responsive and support card adds and removes.
3+
It is responsive and support dynamic card adds and removes.
44

5+
You decide how many cards will be simultaneously visible depending on screen size, in the bootstrap style. You can then navigate to the other cards depending on how you want to implement it. If you don't want to implement anything, you can use default arrows.
56

6-
For example you can have 3 cards on the screen and there is a total of 5 cards, you can navigate right or left to the cards not displayed.
7-
You resize and you display only 2 cards, you can still navigate to the other cards.
7+
Visually you have a left stack of cards, visible cards in the middle, and a right stack.
88

9-
Navigation can also be triggered programmatically.
10-
11-
## New in 1.x
12-
No need to give card width and card count anymore
9+
## New in 2.x
10+
Using stacks instead of sliding cards out of the screen
11+
Doesn't use react-motion anymore
1312

1413
## Installation
1514
```bash
@@ -18,24 +17,33 @@ npm i -S react-card-scroll
1817

1918
## Usage
2019

21-
Import css ```~react-card-scroll/lib/assets/styles.css```
20+
Import css either in sass ```~react-card-scroll/lib/assets/styles.css``` or in javascript with webpack
21+
22+
Use bootstrap style to decide how many cards will be visible (just add ```rcs-```): ```rcs-col-*-*```. You don't have to include bootstrap.
23+
24+
Choose how you want to implement the navigation by using ```scrollCards({toLeft: true/false, number:*})```.For example, you can scroll when you click on a stack or when you wheel your mouse with the pointer on a card title.
25+
See the example: ```npm run example``` and open localhost:8081. And get inspiration from the source code.
2226

27+
You can know where a card is with the ```getCardOffset``` function in JavaScript, or with the CSS classes ```rcs-left-stack rcs-center rcs-right-stack```
2328

29+
Use arrows with props ```showArrows={true}```
30+
31+
## Some (very) basic usage
2432
```jsx
2533
<CardScroll ref="cardScroll">
26-
<div className="col-sm-6 col-md-4">
34+
<div className="rcs-col-sm-6 rcs-col-md-4">
2735
</div>
2836

29-
<div className="col-sm-6 col-md-4">
37+
<div className="rcs-col-sm-6 rcs-col-md-4">
3038
</div>
3139

32-
<div className="col-sm-6 col-md-4">
40+
<div className="rcs-col-sm-6 rcs-col-md-4">
3341
</div>
3442

35-
<div className="col-sm-6 col-md-4">
43+
<div className="rcs-col-sm-6 rcs-col-md-4">
3644
</div>
3745

38-
<div className="col-sm-6 col-md-4">
46+
<div className="rcs-col-sm-6 rcs-col-md-4">
3947
</div>
4048
</CardScroll>
4149
```
@@ -46,15 +54,14 @@ From parent, trigger navigation when you want (add or remove cards, click somewh
4654
this.refs.cardScroll.scrollCards({toLeft: true, number:1})
4755
```
4856

49-
50-
5157
## TODO
52-
- [ ] Tests
58+
- [x] Tests
5359
- [x] Example
5460
- Features
5561
- [x] CSS arrows
5662
- [x] Disable arrows if unable to navigate
57-
~~- [ ] Mouse scroll triggers horizontal scroll~~ (it is up to the user, see example)
63+
- [ ] ~~Mouse scroll triggers horizontal scroll~~ (it is up to the user, see example)
64+
- [x] Stacks
5865
- Fix
5966
- [x] Remove horizontal scroll bar
6067
- Technical

example/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8">
55
<title>React-card-scroll example</title>
66
</head>
7-
<body style="overflow-x: hidden">
7+
<body>
88
<div id="example"></div>
99
</body>
1010
</html>

example/index.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,26 @@ import CardScroll from '../lib'
55
const ScrollableTitleCard = React.createClass({
66
componentDidMount() {
77
this.refs.title.addEventListener('wheel', event => {
8-
this.props.onScrollTitle({toLeft:event.wheelDelta>0})
8+
this.props.scrollCards({toLeft:event.wheelDelta>0})
99
event.preventDefault()
1010
})
1111
},
1212
render() {
13-
const {title, children} = this.props
13+
const {title, children, className, style} = this.props
14+
const onClick = ev => {
15+
const offset = this.props.getCardOffset()
16+
if(offset!=0){
17+
ev.preventDefault()
18+
this.props.scrollCards({toLeft:offset<0})
19+
}
20+
}
1421
return (
15-
<div className="col-sm-6 col-md-4">
16-
<div className="card">
22+
<div className={"col rcs-col-sm-6 rcs-col-md-4 rcs-col-lg-3 "+className} style={style}>
23+
<div onClick={onClick} className="card">
1724
<div ref="title" className="card-header">
1825
{title}
1926
</div>
20-
<div className="card-body">
27+
<div className="card-block">
2128
{children}
2229
</div>
2330
</div>
@@ -64,13 +71,14 @@ const Example = React.createClass({
6471
},
6572

6673
render() {
67-
const onScrollTitle = params => this.refs.cardScroll.scrollCards(params)
74+
const scrollCards = params => this.refs.cardScroll.scrollCards(params)
75+
const getCardOffset = index => () => this.refs.cardScroll.getCardOffset(index)
6876
return (
6977
<div>
7078
<button onClick={this.addCard}>Add card</button>
7179
<button onClick={this.removeCard}>Remove last card</button>
7280
<CardScroll ref="cardScroll">
73-
{this.state.cards.map(el => React.cloneElement(el, {onScrollTitle}))}
81+
{this.state.cards.map((el, index) => React.cloneElement(el, {scrollCards, getCardOffset:getCardOffset(index)}))}
7482
</CardScroll>
7583
</div>
7684
)

example/theme.scss

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
11
$enable-flex: true;
22

33
@import "../node_modules/bootstrap/scss/bootstrap";
4+
45
@import "../lib/assets/styles.css";
56

7+
.col{
8+
pointer-events: none;
9+
}
10+
11+
.card {
12+
pointer-events: auto;
13+
}
14+
615
.card-header{
716
&:hover{
817
background-image: linear-gradient(0, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1));
918
}
1019
}
20+
21+
.rcs-left-stack,.rcs-right-stack{
22+
.card:hover {
23+
background-image: linear-gradient(0, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1));
24+
cursor: pointer;
25+
}
26+
}

lib/assets/styles.css

Lines changed: 154 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
.row._1H7C65wd8WJqBtCRmAfokb {
2-
display: flex;
3-
flex-wrap: nowrap;
4-
position: relative; }
1+
._1H7C65wd8WJqBtCRmAfokb {
2+
position: relative;
3+
box-sizing: border-box; }
4+
5+
._1H7C65wd8WJqBtCRmAfokb ._358enaiolY7BZPuXLuxdRA {
6+
position: absolute;
7+
transition: left 1s cubic-bezier(0, 0.7, 0.7, 1);
8+
box-sizing: border-box; }
59

610
._22yQcZhJvmCSA52vE9VrUe {
711
position: fixed;
@@ -49,3 +53,149 @@
4953
._1bIeR72ojeoWY-MxcIhjT-:hover {
5054
background: linear-gradient(to left, #ddd, #ccc);
5155
margin-left: 0; }
56+
57+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-1, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-2, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-3, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-4, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-5, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-6, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-7, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-8, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-9, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-10, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-11, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-12, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-1, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-2, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-3, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-4, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-5, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-6, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-7, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-8, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-9, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-10, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-11, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-12, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-1, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-2, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-3, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-4, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-5, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-6, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-7, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-8, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-9, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-10, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-11, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-12, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-1, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-2, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-3, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-4, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-5, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-6, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-7, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-8, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-9, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-10, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-11, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-12, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-1, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-2, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-3, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-4, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-5, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-6, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-7, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-8, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-9, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-10, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-11, ._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-12 {
58+
min-height: 1px;
59+
padding-left: 0.9375rem;
60+
padding-right: 0.9375rem;
61+
width: 100%; }
62+
63+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-1 {
64+
width: 8.33333%; }
65+
66+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-2 {
67+
width: 16.66667%; }
68+
69+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-3 {
70+
width: 25%; }
71+
72+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-4 {
73+
width: 33.33333%; }
74+
75+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-5 {
76+
width: 41.66667%; }
77+
78+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-6 {
79+
width: 50%; }
80+
81+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-7 {
82+
width: 58.33333%; }
83+
84+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-8 {
85+
width: 66.66667%; }
86+
87+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-9 {
88+
width: 75%; }
89+
90+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-10 {
91+
width: 83.33333%; }
92+
93+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-11 {
94+
width: 91.66667%; }
95+
96+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xs-12 {
97+
width: 100%; }
98+
99+
@media (min-width: 544px) {
100+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-1 {
101+
width: 8.33333%; }
102+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-2 {
103+
width: 16.66667%; }
104+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-3 {
105+
width: 25%; }
106+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-4 {
107+
width: 33.33333%; }
108+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-5 {
109+
width: 41.66667%; }
110+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-6 {
111+
width: 50%; }
112+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-7 {
113+
width: 58.33333%; }
114+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-8 {
115+
width: 66.66667%; }
116+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-9 {
117+
width: 75%; }
118+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-10 {
119+
width: 83.33333%; }
120+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-11 {
121+
width: 91.66667%; }
122+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-sm-12 {
123+
width: 100%; } }
124+
125+
@media (min-width: 768px) {
126+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-1 {
127+
width: 8.33333%; }
128+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-2 {
129+
width: 16.66667%; }
130+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-3 {
131+
width: 25%; }
132+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-4 {
133+
width: 33.33333%; }
134+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-5 {
135+
width: 41.66667%; }
136+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-6 {
137+
width: 50%; }
138+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-7 {
139+
width: 58.33333%; }
140+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-8 {
141+
width: 66.66667%; }
142+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-9 {
143+
width: 75%; }
144+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-10 {
145+
width: 83.33333%; }
146+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-11 {
147+
width: 91.66667%; }
148+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-md-12 {
149+
width: 100%; } }
150+
151+
@media (min-width: 992px) {
152+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-1 {
153+
width: 8.33333%; }
154+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-2 {
155+
width: 16.66667%; }
156+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-3 {
157+
width: 25%; }
158+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-4 {
159+
width: 33.33333%; }
160+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-5 {
161+
width: 41.66667%; }
162+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-6 {
163+
width: 50%; }
164+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-7 {
165+
width: 58.33333%; }
166+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-8 {
167+
width: 66.66667%; }
168+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-9 {
169+
width: 75%; }
170+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-10 {
171+
width: 83.33333%; }
172+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-11 {
173+
width: 91.66667%; }
174+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-lg-12 {
175+
width: 100%; } }
176+
177+
@media (min-width: 1200px) {
178+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-1 {
179+
width: 8.33333%; }
180+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-2 {
181+
width: 16.66667%; }
182+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-3 {
183+
width: 25%; }
184+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-4 {
185+
width: 33.33333%; }
186+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-5 {
187+
width: 41.66667%; }
188+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-6 {
189+
width: 50%; }
190+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-7 {
191+
width: 58.33333%; }
192+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-8 {
193+
width: 66.66667%; }
194+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-9 {
195+
width: 75%; }
196+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-10 {
197+
width: 83.33333%; }
198+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-11 {
199+
width: 91.66667%; }
200+
._1H7C65wd8WJqBtCRmAfokb .rcs-col-xl-12 {
201+
width: 100%; } }

0 commit comments

Comments
 (0)