@yoursurprise/slider 2.2.0-beta.3 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -9
- package/package.json +1 -1
- package/src/Slider.test.tsx +49 -1
- package/dist/Examples/OnSlideExample.d.ts +0 -4
- package/src/Examples/OnSlideExample.tsx +0 -40
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# React slider
|
|
2
2
|
|
|
3
3
|
This package contains a basic modern slider. The purpose of this slider is to provide a simple React component
|
|
4
|
-
which can be controlled in a userfriendly way on mobile, tablet and desktop.
|
|
4
|
+
which can be controlled in a userfriendly way on mobile, tablet and desktop.
|
|
5
5
|
|
|
6
6
|
Demo page: https://yoursurprisecom.github.io/slider/
|
|
7
7
|
|
|
8
|
-
This slider has the following features:
|
|
8
|
+
This slider has the following features:
|
|
9
9
|
|
|
10
10
|
- Free scroll on mobile with native CSS scroll snapping
|
|
11
11
|
- Drag to scroll on devices with a mouse
|
|
@@ -13,6 +13,7 @@ This slider has the following features:
|
|
|
13
13
|
- Support for multiple variable width slides
|
|
14
14
|
|
|
15
15
|
Todos (help appreciated):
|
|
16
|
+
|
|
16
17
|
- ~~Add a demo page~~
|
|
17
18
|
- Add more configuration
|
|
18
19
|
- Add end-to-end tests
|
|
@@ -22,11 +23,12 @@ Todos (help appreciated):
|
|
|
22
23
|
- Improve accessibility
|
|
23
24
|
- Reduce amount of required tooling
|
|
24
25
|
|
|
25
|
-
All browsers with [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
|
|
26
|
+
All browsers with [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
|
|
27
|
+
will be supported, as of right now, only the latest versions of browsers are supported.
|
|
26
28
|
|
|
27
29
|
## Installation
|
|
28
30
|
|
|
29
|
-
### npm
|
|
31
|
+
### npm
|
|
30
32
|
|
|
31
33
|
`npm install @yoursurprise/slider --save`
|
|
32
34
|
|
|
@@ -43,7 +45,7 @@ import "@yoursurprise/slider/dist/index.css";
|
|
|
43
45
|
### Implement the Slider
|
|
44
46
|
|
|
45
47
|
```javascript
|
|
46
|
-
import {
|
|
48
|
+
import {Slider} from '@yoursurprise/slider';
|
|
47
49
|
import '@yoursurprise/slider/dist/index.css';
|
|
48
50
|
|
|
49
51
|
export default function YourComponent() {
|
|
@@ -60,7 +62,39 @@ export default function YourComponent() {
|
|
|
60
62
|
|
|
61
63
|
### Configuration
|
|
62
64
|
|
|
63
|
-
| Option | Type
|
|
64
|
-
|
|
65
|
-
| hideNavigationButtons | `boolean`
|
|
66
|
-
| initialSlideIndex | `number`
|
|
65
|
+
| Option | Type | Required | Default | Description |
|
|
66
|
+
|-----------------------|------------|----------|-------------|---------------------------------------------------------|
|
|
67
|
+
| hideNavigationButtons | `boolean` | `false` | `false` | Always hides the navigation buttons |
|
|
68
|
+
| initialSlideIndex | `number` | `false` | `0` | Open the Slider at a specific index |
|
|
69
|
+
| onSlide | `function` | `false` | `undefined` | A callback function that is called when the user slides |
|
|
70
|
+
|
|
71
|
+
### API
|
|
72
|
+
|
|
73
|
+
| API method | Type | Returns | Description |
|
|
74
|
+
|--------------------------------|------------|----------|----------------------------------------------|
|
|
75
|
+
| getFirstFullyVisibleSlideIndex | `function` | `number` | Retrieve the first fully visible slide index |
|
|
76
|
+
| getLastFullyVisibleSlideIndex | `function` | `number` | Retrieve the last fully visible slide index |
|
|
77
|
+
| scrollToSlide | `function` | `void` | Scroll the slider to a specific slide |
|
|
78
|
+
|
|
79
|
+
#### Example on how to access the slider API:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
export default function YourComponent() {
|
|
83
|
+
const sliderApi = useRef();
|
|
84
|
+
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (sliderApi.current) {
|
|
87
|
+
sliderApi.current.getFirstFullyVisibleSlideIndex();
|
|
88
|
+
}
|
|
89
|
+
}, [sliderApi.current]);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<Slider ref={sliderApi}>
|
|
93
|
+
<div>1</div>
|
|
94
|
+
<div>2</div>
|
|
95
|
+
<div>3</div>
|
|
96
|
+
<div>4</div>
|
|
97
|
+
</Slider>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
package/package.json
CHANGED
package/src/Slider.test.tsx
CHANGED
|
@@ -157,7 +157,7 @@ describe('UpsellSlider', () => {
|
|
|
157
157
|
await userEvent.click(screen.getByTestId('1'));
|
|
158
158
|
|
|
159
159
|
await waitFor(() => {
|
|
160
|
-
expect(clickSpy).
|
|
160
|
+
expect(clickSpy).toHaveBeenCalledTimes(1);
|
|
161
161
|
});
|
|
162
162
|
});
|
|
163
163
|
});
|
|
@@ -367,4 +367,52 @@ describe('UpsellSlider', () => {
|
|
|
367
367
|
expect(ref.current!.getLastFullyVisibleSlideIndex()).toBe(2);
|
|
368
368
|
});
|
|
369
369
|
});
|
|
370
|
+
|
|
371
|
+
describe('scrollToSlide', () => {
|
|
372
|
+
it('scrolls to the next slide', async () => {
|
|
373
|
+
const ref = React.createRef<API>();
|
|
374
|
+
render(<Slider ref={ref}>
|
|
375
|
+
<span key={1}/>
|
|
376
|
+
<span key={2}/>
|
|
377
|
+
<span key={3}/>
|
|
378
|
+
<span key={4}/>
|
|
379
|
+
</Slider>);
|
|
380
|
+
|
|
381
|
+
const slides = screen.getAllByRole('listitem');
|
|
382
|
+
|
|
383
|
+
slides.forEach((child, i) => {
|
|
384
|
+
Object.defineProperty(child, 'clientWidth', { configurable: true, value: 500 });
|
|
385
|
+
Object.defineProperty(child, 'offsetLeft', { value: 500 * (i + 1) });
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
act(() => {
|
|
389
|
+
if (ref.current !== null) {
|
|
390
|
+
ref.current.scrollToSlide(2, 'smooth');
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
await waitFor(() => {
|
|
395
|
+
expect(scrollToSpy).toHaveBeenCalledWith({
|
|
396
|
+
behavior: 'smooth',
|
|
397
|
+
left: 1500,
|
|
398
|
+
top: 0,
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
describe('initialSlideIndex', () => {
|
|
405
|
+
it('Opens the slider with the initialSlide', async () => {
|
|
406
|
+
render(<Slider initialSlideIndex={2}>
|
|
407
|
+
<span key={ 1 } data-testid="child-1"/>
|
|
408
|
+
<span key={ 2 } data-testid="child-2"/>
|
|
409
|
+
<span key={ 3 } data-testid="child-3"/>
|
|
410
|
+
<span key={ 4 } data-testid="child-4"/>
|
|
411
|
+
</Slider>);
|
|
412
|
+
|
|
413
|
+
await waitFor(() => {
|
|
414
|
+
expect(scrollToSpy).toHaveBeenCalledTimes(1);
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
});
|
|
370
418
|
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { FC, PropsWithChildren, ComponentType } from 'react';
|
|
2
|
-
import { useRef, useState } from 'react';
|
|
3
|
-
import { Slider, SliderTypes } from '../Slider';
|
|
4
|
-
|
|
5
|
-
const OnSlideExample: FC<typeof Slider extends ComponentType<infer T> ? PropsWithChildren<T> : never> = (sliderProps) => {
|
|
6
|
-
const sliderApi = useRef<SliderTypes.API>(null);
|
|
7
|
-
const [firstVisibleSlideIndex, setFirstVisibleSlideIndex] = useState<number>(0);
|
|
8
|
-
const [lastVisibleSlideIndex, setLastVisibleSlideIndex] = useState<number>(0);
|
|
9
|
-
|
|
10
|
-
const slides: JSX.Element[] = [
|
|
11
|
-
<div key="slide 1" className="demo-slide demo-slide--fixed" style={{ backgroundColor: 'rgb(50, 50, 50)' }}>Slide 1</div>,
|
|
12
|
-
<div key="slide 2" className="demo-slide demo-slide--fixed" style={{ backgroundColor: 'rgb(75, 75, 75)' }}>Slide 2</div>,
|
|
13
|
-
<div key="slide 3" className="demo-slide demo-slide--fixed" style={{ backgroundColor: 'rgb(100, 100, 100)' }}>Slide 3</div>,
|
|
14
|
-
<div key="slide 4" className="demo-slide demo-slide--fixed" style={{ backgroundColor: 'rgb(125, 125, 125)' }}>Slide 4</div>,
|
|
15
|
-
<div key="slide 5" className="demo-slide demo-slide--fixed" style={{ backgroundColor: 'rgb(150, 150, 150)' }}>Slide 5</div>,
|
|
16
|
-
<div key="slide 6" className="demo-slide demo-slide--fixed" style={{ backgroundColor: 'rgb(175, 175, 175)' }}>Slide 6</div>,
|
|
17
|
-
<div key="slide 7" className="demo-slide demo-slide--fixed" style={{ backgroundColor: 'rgb(200, 200, 200)' }}>Slide 7</div>,
|
|
18
|
-
<div key="slide 8" className="demo-slide demo-slide--fixed" style={{ backgroundColor: 'rgb(225, 225, 225)' }}>Slide 8</div>,
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
const onSlide = () => {
|
|
22
|
-
if (sliderApi.current) {
|
|
23
|
-
setFirstVisibleSlideIndex(sliderApi.current.getFirstFullyVisibleSlideIndex());
|
|
24
|
-
setLastVisibleSlideIndex(sliderApi.current.getLastFullyVisibleSlideIndex());
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<>
|
|
30
|
-
<h1>Slides visibility</h1>
|
|
31
|
-
<div>First fully visible slide: {firstVisibleSlideIndex + 1}</div>
|
|
32
|
-
<div>Last fully visible slide: {lastVisibleSlideIndex + 1}</div>
|
|
33
|
-
<Slider {...sliderProps} onSlide={onSlide} ref={sliderApi}>
|
|
34
|
-
{slides}
|
|
35
|
-
</Slider>
|
|
36
|
-
</>
|
|
37
|
-
);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export default OnSlideExample;
|