Skip to content

Commit 5005742

Browse files
authored
Updating Simple Carousel Documentation and Contribution Documention (#352)
1 parent 2cd8335 commit 5005742

File tree

4 files changed

+148
-23
lines changed

4 files changed

+148
-23
lines changed

CONTRIBUTING.md

+18-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ We encourage pull requests concerning:
1616

1717
## Development
1818

19-
Initial install & setup, with **node 10+** & **yarn v1**, run `yarn install`.
19+
Initial install & setup, with **node 16** & **yarn v1**, run `yarn install`.
2020

2121
Make changes/updates to the `src/index.ts` file.
2222

@@ -27,12 +27,10 @@ Make changes/updates to the `src/index.ts` file.
2727
Build, run, and test examples locally:
2828

2929
```sh
30-
# Go into examples folder
31-
react-swipeable$ cd examples
3230
# Yarn install
33-
react-swipeable/examples$ yarn
31+
yarn install
3432
# Run the start:dev:local command
35-
react-swipeable/examples$ yarn start:dev:local
33+
yarn start:examples:local
3634
```
3735

3836
Then open a browser tab to `http://localhost:8080/`.
@@ -50,6 +48,19 @@ All these steps can be verified via a single command.
5048
yarn test
5149
```
5250

51+
## Documentation
52+
53+
Documentation is managed within the `docs` directory. In order to test and preview changes, you'll require Node 18+ to run locally.
54+
55+
```sh
56+
# navigate to docs directory
57+
cd docs
58+
# install modules
59+
docs$ yarn install
60+
# start locally and view at http://localhost:3000/
61+
docs$ yarn start
62+
```
63+
5364
### Unit Testing
5465

5566
All unit tests are located in:
@@ -193,4 +204,6 @@ examples$ python -m http.server 8080
193204
```sh
194205
# From root - build and publish the examples app to github pages
195206
$ yarn examples:build:publish
207+
208+
196209
```

docs/docs/examples/simple-carousel.mdx

+130-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,136 @@ import SimpleCarousel from '@site/src/components/examples/SimpleCarousel'
44

55
# Simple Carousel
66

7-
Below is an example implementation of a simple carousel which utilizes the hooks provided by react-swipeable.
7+
Below is an example implementation of a simple carousel which utilizes the hooks provided by `react-swipeable` within a TypeScript context.
8+
9+
10+
## Simple Carousel Code Source
11+
12+
You can see this full example as pure code within the [Carousel.tsx](https://github.com/FormidableLabs/react-swipeable/blob/main/examples/app/SimpleCarousel/Carousel.tsx) file within the React-Swipeable repo directly.
13+
14+
## Simple Carousel Live Preview
815

916
<SimpleCarousel />
1017

18+
Note: The action of swiping must have a duration of `500ms` or lower in order to trigger the swipe action.
19+
20+
## Simple Carousel Code Explained
21+
22+
Import the hook directly from the `react-swipeable` library. In our example, we built and imported a local set of UI components: you can utilize your own UI and styling, or use your favorite UI component library of choice.
23+
24+
```typescript
25+
import { useSwipeable } from 'react-swipeable';
26+
import {
27+
Wrapper,
28+
CarouselContainer,
29+
CarouselSlot,
30+
SlideButtonContainer,
31+
SlideButton,
32+
PREV,
33+
NEXT
34+
} from '../components';
35+
```
36+
37+
Below, we set up types and an interface for some of the work we'll be building. Next, we write a function called `getOrder`, which will drive the position of each item in the carousel, and what order of position each will be displayed in context of the carousel. Finally, we have a simple `getInitialState` position that sets the `CarouselState` of the carousel we'll be building.
38+
39+
```typescript
40+
type Direction = typeof PREV | typeof NEXT;
41+
42+
interface CarouselState {
43+
pos: number;
44+
sliding: boolean;
45+
dir: Direction;
46+
}
47+
48+
type CarouselAction =
49+
| { type: Direction, numItems: number }
50+
| { type: 'stopSliding' };
51+
52+
53+
const getOrder = (index: number, pos: number, numItems: number) => {
54+
return index - pos < 0 ? numItems - Math.abs(index - pos) : index - pos;
55+
};
56+
57+
const getInitialState = (numItems: number): CarouselState => ({ pos: numItems - 1, sliding: false, dir: NEXT });
58+
```
59+
60+
Next, we build a reducer for controlling the action of the Carousel, using a switch to set `CarouselState` logic.
61+
62+
```typescript
63+
function reducer(state: CarouselState, action: CarouselAction): CarouselState {
64+
switch (action.type) {
65+
case PREV:
66+
return {
67+
...state,
68+
dir: PREV,
69+
sliding: true,
70+
pos: state.pos === 0 ? action.numItems - 1 : state.pos - 1
71+
};
72+
case NEXT:
73+
return {
74+
...state,
75+
dir: NEXT,
76+
sliding: true,
77+
pos: state.pos === action.numItems - 1 ? 0 : state.pos + 1
78+
};
79+
case 'stopSliding':
80+
return { ...state, sliding: false };
81+
default:
82+
return state;
83+
}
84+
}
85+
```
86+
87+
Then, building upon the reducer logic, the `<Carousel>` is constructed. We hold the number of items within a count of `numItems`. We utilize the reducer within the `React.useReducer` hook.
88+
89+
By creating `slide`, as a `const`, we can utilize that later in the component, calling it within `useSwipeable`: called upon `slide(NEXT)` and `slide(PREV)`, invoking the `dispatch` and the `timeout` we built within `slide`. Within the use of `useSwippeable`, we set `swipeDuration` to `500ms`. We set `preventScrollOnSwipe` to `true`, and `trackMouse` to `true`.
90+
91+
At the end, we return the component itself, built with the components we've created, with `handlers` passed into the wrapping `<div>` around the surrounding container. The `<CarouselContainer>` holds the directional and sliding state, and within that container the items we want to display are mapped as `React.Children`, utilizing `getOrder`.
92+
93+
When we put it all together, our `<Carousel>` is complete!
94+
95+
```typescript
96+
const Carousel: FunctionComponent<{children: ReactNode}> = (props) => {
97+
const numItems = React.Children.count(props.children);
98+
const [state, dispatch] = React.useReducer(reducer, getInitialState(numItems));
99+
100+
const slide = (dir: Direction) => {
101+
dispatch({ type: dir, numItems });
102+
setTimeout(() => {
103+
dispatch({ type: 'stopSliding' });
104+
}, 50);
105+
};
106+
107+
const handlers = useSwipeable({
108+
onSwipedLeft: () => slide(NEXT),
109+
onSwipedRight: () => slide(PREV),
110+
swipeDuration: 500,
111+
preventScrollOnSwipe: true,
112+
trackMouse: true
113+
});
114+
115+
return (
116+
<div {...handlers}>
117+
<Wrapper>
118+
<CarouselContainer dir={state.dir} sliding={state.sliding}>
119+
{React.Children.map(props.children, (child, index) => (
120+
<CarouselSlot
121+
order={getOrder(index, state.pos, numItems)}
122+
>
123+
{child}
124+
</CarouselSlot>
125+
))}
126+
</CarouselContainer>
127+
</Wrapper>
128+
<SlideButtonContainer>
129+
<SlideButton onClick={() => slide(PREV)} float="left">
130+
Prev
131+
</SlideButton>
132+
<SlideButton onClick={() => slide(NEXT)} float="right">
133+
Next
134+
</SlideButton>
135+
</SlideButtonContainer>
136+
</div>
137+
);
138+
};
139+
```

docs/src/components/examples/SimpleCarousel/index.tsx

-9
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,6 @@ function SimpleCarousel() {
1616
<Item src={Product4} />
1717
<Item src={Product5} />
1818
</Carousel>
19-
<b>Note: swipe must be "faster" than 500ms to trigger.</b>
20-
<h6>
21-
<a href="https://github.com/FormidableLabs/react-swipeable/blob/main/examples/app/SimpleCarousel/Carousel.tsx">
22-
See code
23-
</a>{" "}
24-
for example usage of{" "}
25-
<code style={{ whiteSpace: "nowrap" }}>swipeDuration</code> and{" "}
26-
<code>preventScrollOnSwipe</code>.
27-
</h6>
2819
</div>
2920
);
3021
}

examples/app/SimpleCarousel/index.tsx

-8
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,13 @@ import Carousel from './Carousel';
77
function SimpleCarousel() {
88
return (
99
<div>
10-
<h5 style={{ marginBottom: '20px' }}>
11-
<strong>🖼 Image Carousel</strong>
12-
</h5>
13-
1410
<Carousel>
1511
<Item img="https://unsplash.it/475/205" />
1612
<Item img="https://unsplash.it/476/205" />
1713
<Item img="https://unsplash.it/477/205" />
1814
<Item img="https://unsplash.it/478/205" />
1915
<Item img="https://unsplash.it/479/205" />
2016
</Carousel>
21-
<b>Note: swipe must be "faster" then 500ms to trigger.</b>
22-
<h6>
23-
<a href="https://github.com/FormidableLabs/react-swipeable/blob/main/examples/app/SimpleCarousel/Carousel.tsx">See code</a> for example usage of <code style={{ whiteSpace: "nowrap" }}>swipeDuration</code> and <code>preventScrollOnSwipe</code>.
24-
</h6>
2517
</div>
2618
);
2719
}

0 commit comments

Comments
 (0)