@yoursurprise/slider 2.2.0-beta.2 → 2.2.0-beta.4

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 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) will be supported, as of right now, only the latest versions of browsers are supported.
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 { Slider } from '@yoursurprise/slider';
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 | Required | Default | Description |
64
- |-----------------------|-----------|----------|---------|-------------------------------------|
65
- | hideNavigationButtons | `boolean` | `false` | `false` | Always hides the navigation buttons |
66
- | initialSlideIndex | `number` | `false` | `0` | Open the Slider at a specific index |
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/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- import { Slider, SliderTypes } from './Slider';
2
- export { Slider, SliderTypes };
1
+ import { Slider } from './Slider';
2
+ import type { SliderTypes } from './Slider';
3
+ export { Slider };
4
+ export type { SliderTypes };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yoursurprise/slider",
3
- "version": "2.2.0-beta.2",
3
+ "version": "2.2.0-beta.4",
4
4
  "description": "Basic React slider using modern Javascript and CSS",
5
5
  "module": "dist/module.js",
6
6
  "main": "dist/index.js",
@@ -157,7 +157,7 @@ describe('UpsellSlider', () => {
157
157
  await userEvent.click(screen.getByTestId('1'));
158
158
 
159
159
  await waitFor(() => {
160
- expect(clickSpy).toHaveBeenCalled();
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
  });
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
- import { Slider, SliderTypes } from './Slider';
1
+ import { Slider } from './Slider';
2
+ import type { SliderTypes } from './Slider';
2
3
 
3
- export { Slider, SliderTypes };
4
+ export { Slider };
5
+ export type { SliderTypes };
@@ -1,4 +0,0 @@
1
- import type { FC, PropsWithChildren, ComponentType } from 'react';
2
- import { Slider } from '../Slider';
3
- declare const OnSlideExample: FC<typeof Slider extends ComponentType<infer T> ? PropsWithChildren<T> : never>;
4
- export default OnSlideExample;
@@ -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;