diff --git a/.babelrc b/.babelrc
index 5c828aeba..8d40400c0 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,7 +1,9 @@
{
- "presets":[
- "react",
- ["es2015", {"loose": true}]
+ "presets": [
+ "@babel/preset-env",
+ "@babel/preset-react"
],
- "plugins": ["transform-object-assign", "transform-object-rest-spread"]
+ "plugins": [
+ "@babel/plugin-proposal-class-properties"
+ ]
}
diff --git a/.eslintrc b/.eslintrc
index 452e4d39a..563dcfb00 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -3,13 +3,14 @@
"no-extra-parens": 0,
"react/jsx-uses-vars": 1,
"strict": 0,
- "quotes": [2, "single"],
"no-underscore-dangle": 0,
"space-infix-ops": 0,
- "no-alert": 0
- },
- "ecmaFeatures": {
- "jsx": true,
+ "no-alert": 0,
+ "react/prop-types": 0,
+ "react/no-find-dom-node": 0,
+ "react/display-name": 0,
+ "no-console": 0,
+ "no-prototype-builtins": 0
},
"env": {
"node": true,
@@ -17,8 +18,17 @@
"es6": true,
"jasmine": true
},
- "parser": "babel-eslint",
+ "parser": "@babel/eslint-parser",
+ "parserOptions": {
+ "requireConfigFile": false
+ },
"plugins": [
- "react"
+ "react",
+ "import"
+ ],
+ "extends": [
+ "eslint:recommended",
+ "plugin:import/errors",
+ "plugin:react/recommended"
]
-}
+}
\ No newline at end of file
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..e26119c87
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+github: akiran
+open_collective: react-slick
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..b6d69fe35
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,6 @@
+
+
+### Guidelines for posting a new issue
+
+* Please replicate your issue with this [CodeSandBox](https://codesandbox.io/s/ppwkk5l6xx) and provide a link to it along with the issue description
diff --git a/.gitignore b/.gitignore
index 0924803f2..308ee06ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,18 @@ npm-debug.log
lib
*.sublime-*
.idea
-dist
\ No newline at end of file
+dist
+yarn.lock
+.vscode
+exampleslib
+examples/scripts/configs.json
+jquery.html
+docs/fonts/
+docs/ajax-loader.gif
+package-lock.json
+.DS_Store
+/test-results/
+/playwright-report/
+/blob-report/
+/playwright/.cache/
+src-jsx
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index e2bf06386..000000000
--- a/.jshintrc
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "esnext": true,
- "strict": true,
- "globalstrict": true,
- "node": true,
- "mocha": true,
- "browser": true,
- "bitwise": true,
- "camelcase": true,
- "curly": true,
- "eqeqeq": true,
- "immed": true,
- "indent": 2,
- "latedef": true,
- "newcap": true,
- "noarg": true,
- "undef": true,
- "unused": true
-}
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 000000000..cbc61f68e
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1 @@
+trailingComma: none
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 6998e3244..4ed0ffaed 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,5 @@
language: node_js
+
node_js:
- - "stable"
\ No newline at end of file
+ - "stable"
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..0cd5a876f
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,125 @@
+# Change Log
+
+## [Unreleased](https://github.com/akiran/react-slick/tree/HEAD)
+
+## 0.22.0
+
+**Release Changes**
+
+- Internal Changes
+ - converted InnerSlider from createReactClass object to ES6 class
+ - removed all the mixins, created classMethods and pure utility functions instead
+ - changed autoplay from setTimeout to setInterval
+ - added images onload handlers to update dynamically
+ - added autoplaying state for the betterment of autoplay and pause
+ - removed usage of assign or Object.assign, using object spreading instead
+ - implemented effects of touchMove props
+ - fixed transition in opposite direction in case of continuous scrolling
+ - added separate onclick event listener for images
+ - added missing classes `regular` and `slider`
+ - renamed events
+ - edgeEvent => onEdge
+ - init => onInit
+ - reInit => onReInit
+ - implemented `pauseOnDotsHover` property
+ - implemented Progressive LazyLoad property, lazyLoad is now ondemand/progressive
+ - implemented lazyloadError event
+ - implemented useTransform property
+ - implemented pauseOnFocus property
+ - added resize observer to update on slider resize
+
+- Bug Fixes
+ - dynamic track updates on image load
+ - fixed slickPause and autoPlay issues (paused slider would resume autoplay sometime)
+ - fixed trackStyle update on window resize
+ - fixed NodeList forEach problem for chrome 51 or below
+ - fixed bugs due to uncleared callback timers
+ - fixed update issues on just slider resize
+
+
+## 0.21.0
+
+**Release Changes**
+
+- Fixed issues
+ - dataset undefined error in case of swipeToSlide but finite slides
+ - slideWidth issue by transform scale
+ - variableWidth + finite alignment problems
+ - wrapper direction rtl issues
+ - added onload update handler for images
+ - fixed breaking of animation on setState
+
+- Mixins to Pure Functions
+ - getWidth, getHeight
+ - swipeDirection
+ - initialize, update
+
+- Other Changes
+ - removed sass, using pure CSS instead
+ - enforced dir='ltr' in the slider, so dir='rtl' in wrapper doesn't break the slider
+ - corrected up/down direction conventions
+ - added more tests along with snapshots
+
+## 0.20.0
+
+**Release Changes**
+
+- handled responsive breakpoint collision
+- renamed autoPlayTimer to autoplayTimer and removed it from state
+- changed es5 module.exports with es6 export default in src/index
+- implemented slider syncing with asNavFor prop
+- made all the slides untabbable
+- implemented getSlick method as in slick
+- implemented slickGetOption method
+- implemented lazyLoaded event
+- implemented reInit event
+- implemented onSwipe event and documented edgeEvent
+
+
+## 0.19.0
+
+**Release Changes**
+
+Following are the changes to be mentioned:
+
+- fixed slideWidth calculation approximation
+- fixed unusual scrolls in focusOnSelect mode
+- added appendDots method for customization of dots
+- modified logic for handling odd/even cases where there were unusual scrolls in opposite direction
+- implemented unslick feature properly
+- fixed variableWidth issues like blank spaces at edges, improper alignment
+- handling focus loss in case of fade=true
+- responsive lazyloading bug fixed
+- increased verticalswiping resistance from 4 to 10
+
+
+## 0.18.0
+
+**Major Changes:**
+
+- `centerPadding` prop now accepts % value as well
+- Fixed dots count in certain cases, where it was wrong
+- Fixed fade property mess-up on click
+- Fixed invisibility issue when fade & vertical are true
+- Modified logic for updating lazyLoadedList, earlier there were some whitespaces at ends, now they're gone
+- Fixed getTrackLeft issue for slideCount=1
+
+
+## 0.17.1
+
+**Major Changes**
+
+* Enforced some settings in specific configurations like:
+ - `slidesToScroll = 1` *when fade is true*
+ - `slidesToScroll = 1` *when centerMode is true*
+ - `slidesToShow = 1` *when fade is true*
+
+* Changed the number of clones (preclones and postclones), that fixed couple of issues like blank spaces after last slide and/or before first slide which occurred in several cases.
+
+
+**Minor Changes**
+
+- Rich amount of tests and test-utilities added
+- Additional documentation comments added
+- Refactored small snippets for betterment
+- Fixed several lazyload and centerMode bugs
diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown
deleted file mode 100644
index 9a6375260..000000000
--- a/CONTRIBUTING.markdown
+++ /dev/null
@@ -1,3 +0,0 @@
-Submitting Pull Requests
-
-* Make sure auto generated files like dist and lib are not part of PR
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..e9ff889b4
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,67 @@
+# Contribute
+
+## Introduction
+
+First, thank you for considering contributing to react-slick! It's people like you that make the open source community such a great community! 😊
+
+We welcome any type of contribution, not only code. You can help with
+- **QA**: file bug reports, the more details you can give the better (e.g. screenshots with the console open)
+- **Marketing**: writing blog posts, howto's, printing stickers, ...
+- **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ...
+- **Code**: take a look at the [open issues](https://github.com/akiran/react-slick/issues). Even if you can't write code, commenting on them, showing that you care about a given issue matters. It helps us triage them. To get started you can also [sign up to triage react-slick issues on CodeTriage](https://www.codetriage.com/akiran/react-slick).
+- **Money**: we welcome financial contributions in full transparency on our [open collective](https://opencollective.com/react-slick).
+
+## Your First Contribution
+
+Working on your first Pull Request? You can learn how from this *free* series, [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github).
+
+## Submitting code
+
+Any code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it. The pull request should also contain tests.
+
+## Code review process
+
+The bigger the pull request, the longer it will take to review and merge. Try to break down large pull requests in smaller chunks that are easier to review and merge.
+It is also always helpful to have some context for your pull request. What was the purpose? Why does it matter to you?
+
+## Financial contributions
+
+We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/react-slick).
+Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed.
+
+## Questions
+
+If you have any questions, create an [issue](https://github.com/akiran/react-slick/issues) (protip: do a quick search first to see if someone else didn't ask the same question before!).
+You can also reach us at hello@react-slick.opencollective.com.
+
+## Credits
+
+### Contributors
+
+Thank you to all the people who have already contributed to react-slick!
+
+
+
+### Backers
+
+Thank you to all our backers! [[Become a backer](https://opencollective.com/react-slick#backer)]
+
+
+
+
+### Sponsors
+
+Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/react-slick#sponsor))
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
deleted file mode 100644
index 40f16bf60..000000000
--- a/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### Guidlines for posting new issue
-
-* Please replicate your issue with this [jsfiddle](https://jsfiddle.net/kirana/20bumb4g/) and provide a link to it along with the issue description
\ No newline at end of file
diff --git a/README.md b/README.md
index 23a7eb93f..713d9a320 100644
--- a/README.md
+++ b/README.md
@@ -1,183 +1,116 @@
-# react-slick
+### react-slick
-[](https://gitter.im/akiran/react-slick?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](#backers) [](#sponsors)
+##### Carousel component built with React. It is a react port of [slick carousel](http://kenwheeler.github.io/slick/)
-Carousel component built with React. It is a react port of [slick carousel](http://kenwheeler.github.io/slick/)
+## [Documentation](http://react-slick.neostack.com)
+### Installation
+**npm**
-### Installation
+```bash
+npm install react-slick --save
+```
+
+**yarn**
```bash
-npm install react-slick
+yarn add react-slick
```
-Also install slick-carousel for css and font
+**Also install slick-carousel for css and font**
```bash
npm install slick-carousel
-@import "~slick-carousel/slick/slick.css";
-@import "~slick-carousel/slick/slick-theme.css";
+
+// Import css files
+import "slick-carousel/slick/slick.css";
+import "slick-carousel/slick/slick-theme.css";
```
or add cdn link in your html
```html
-
-
+
+
```
-### [Demos](http://neostack.com/opensource/react-slick)
-
-### [PlayGround](https://jsfiddle.net/kirana/20bumb4g/)
-Use [jsfiddle template](https://jsfiddle.net/kirana/20bumb4g/) to try react-slick with different settings.
-
-### Filing issues
-Please replicate your issue with [jsfiddle template](https://jsfiddle.net/kirana/20bumb4g/) and post it along with issue to make it easy for me to debug.
-
-
-### Starter Kit
-Checkout [yeoman generator](https://github.com/akiran/generator-react-slick) to quickly
-get started with react-slick.
+### [PlayGround](https://stackblitz.com/edit/vitejs-vite-ownrun?file=src%2FImageSlider.jsx)
### Example
```js
-var React = require('react');
-var Slider = require('react-slick');
-
-class SimpleSlider extends React.Component {
- render: function () {
- var settings = {
- dots: true,
- infinite: true,
- speed: 500,
- slidesToShow: 1,
- slidesToScroll: 1
- };
- return (
-
-
+
+ );
}
```
-| Property | Type | Description | Working |
-| ------------- | ---- | ----------- | ------- |
-| accessibility | bool | Enables tabbing and arrow key navigation | Yes |
-| className | String |Additional class name for the inner slider div | Yes |
-| adaptiveHeight | bool | Adjust the slide's height automatically | Yes |
-| arrows | bool | Should we show Left and right nav arrows | Yes |
-| nextArrow | React Element | Use this element for the next arrow button | Yes |
-| prevArrow | React Element | Use this element for the prev arrow button | Yes |
-| autoplay | bool | Should the scroller auto scroll? | Yes |
-| autoplaySpeed | int | delay between each auto scoll. in ms | Yes |
-| centerMode | bool | Should we centre to a single item? | Yes |
-| centerPadding | | | |
-| cssEase | | | |
-| customPaging | func | Custom paging templates. [Example](https://github.com/akiran/react-slick/blob/master/examples/CustomPaging.js)| Yes |
-| dots | bool | Should we show the dots at the bottom of the gallery | Yes |
-| dotsClass | string | Class applied to the dots if they are enabled | Yes |
-| draggable | bool | Is the gallery scrollable via dragging on desktop? | Yes |
-| easing | string | | |
-| fade | bool | Slides use fade for transition | Yes |
-| focusOnSelect | bool | Go to slide on click | Yes |
-| infinite | bool | should the gallery wrap around it's contents | Yes |
-| initialSlide | int | which item should be the first to be displayed | Yes |
-| lazyLoad | bool | Loads images or renders components on demands | Yes |
-| pauseOnHover | bool | prevents autoplay while hovering | Yes |
-| responsive | array | Array of objects in the form of `{ breakpoint: int, settings: { ... } }` The breakpoint _int_ is the `maxWidth` so the settings will be applied when resolution is below this value. Breakpoints in the array should be ordered from smalles to greatest. Use 'unslick' in place of the settings object to disable rendering the carousel at that breakpoint. Example: `[ { breakpoint: 768, settings: { slidesToShow: 3 } }, { breakpoint: 1024, settings: { slidesToShow: 5 } }, { breakpoint: 100000, settings: 'unslick' } ]`| Yes |
-| rtl | bool | Reverses the slide order | Yes |
-| slide | string |||
-| slidesToShow | int | Number of slides to be visible at a time | Yes |
-| slidesToScroll | int | Number of slides to scroll for each navigation item
-| speed | int |||
-| swipe | bool |||
-| swipeToSlide | bool | Allow users to drag or swipe directly to a slide irrespective of slidesToScroll | Yes |
-| touchMove | bool |||
-| touchThreshold | int |||
-| variableWidth | bool |||
-| useCSS | bool | Enable/Disable CSS Transitions | Yes |
-| vertical | bool | Vertical slide mode | Yes |
-| afterChange | function | callback function called after the current index changes | Yes |
-| beforeChange | function | callback function called before the current index changes | Yes |
-| slickGoTo | int | go to the specified slide number | |
+### Props
+For all available props, go [here](https://react-slick.neostack.com/docs/api/).
### Methods
-* `slickNext()` - function called to change current slide on next slide ([Example](https://github.com/akiran/react-slick/blob/master/examples/PreviousNextMethods.js))
-* `slickPrev()` - function called to change current slide on previous slide ([Example](https://github.com/akiran/react-slick/blob/master/examples/PreviousNextMethods.js))
-* `slickGoTo(slideNumber)` - function called to change current slide to given slide number ([Example](https://github.com/akiran/react-slick/blob/master/examples/SlickGoTo.js))
-
-### Custom next/prev arrows
-
-To customize the next/prev arrow elements, simply create new React components and set them
-as the values of nextArrow and prevArrow.
-
-```js
-class LeftNavButton extends React.Component {
- render() {
- return
- }
-}
-```
-
-Important: be sure that you pass your component's props to your clickable element
-like the example above. If you don't, your custom component won't trigger the click handler.
-
-You can also set `onClick={this.props.onClick}` if you only want to set the click handler.
-
-### Flexbox support
-If you have flex property on container div of slider, add below css
-```css
-* {
- min-height: 0;
- min-width: 0;
-}
-```
-
-### Test Setup
-If you try to run tests with jest in a project that uses react-slick, you my run into this error
-```
-matchMedia not present, legacy browsers require a polyfill
-```
-
-To fix this issue add below snippet in test-setup.js
-```js
-window.matchMedia = window.matchMedia || function() {
- return {
- matches : false,
- addListener : function() {},
- removeListener: function() {}
- };
-};
-
-```
-and add below jest config in package.json
-```json
-"jest": {
- "setupFiles": ["test-setup.js"]
-}
-```
+For all available methods, go [here](https://react-slick.neostack.com/docs/api#methods)
### Development
+
Want to run demos locally
```bash
git clone https://github.com/akiran/react-slick
+cd react-slick
npm install
npm start
open http://localhost:8080
```
-### Polyfills for old IE support
-`matchMedia` support from [media-match](https://github.com/weblinc/media-match)
+## Community
+
+Join our [discord channel](https://discord.gg/z7stRE4Cyb) to discuss react-slick bugs and ask for help
+
+## Contributing
+
+Please see the [contributing guidelines](./CONTRIBUTING.md)
diff --git a/__tests__/SimpleSlider.test.js b/__tests__/SimpleSlider.test.js
new file mode 100644
index 000000000..f0f7b7932
--- /dev/null
+++ b/__tests__/SimpleSlider.test.js
@@ -0,0 +1,46 @@
+// includes tests of
+// SimpleSlider, MultipleItems
+import { testSlider } from "./testUtils";
+
+describe("SimpleSlider with combinations of possibilities", function() {
+ // try around several possibilities
+ let _noOfSlides = [2, 5, 12];
+ let _slidesToShow = [2, 5, 10];
+ let _slidesToScroll = [1, 2, 3, 10];
+ if (true) {
+ // for switching real quick to lesser/easier tests for simplicity
+ _noOfSlides = [5];
+ _slidesToShow = [2];
+ _slidesToScroll = [1, 2];
+ }
+
+ for (let noOfSlides of _noOfSlides) {
+ for (let slidesToShow of _slidesToShow) {
+ for (let slidesToScroll of _slidesToScroll) {
+ // following restrictions may not be 100% correct, and there may be more restrictions
+ if (slidesToShow > noOfSlides || slidesToScroll > slidesToShow) {
+ continue;
+ }
+ if (noOfSlides === slidesToShow) {
+ // temporary, jquery slick disables arrows in this case, so the tests fail
+ continue;
+ }
+ if (slidesToShow === slidesToScroll) {
+ // temporary, active-class is not being assigned properly, so tests fail
+ continue;
+ }
+ const settings1 = {
+ infinite: true,
+ speed: 0,
+ noOfSlides,
+ slidesToShow,
+ slidesToScroll,
+ useCSS: false
+ };
+ test(`Test with settings => noOfSlides: ${noOfSlides}, slidesToShow: ${slidesToShow}, slidesToScroll: ${slidesToScroll}`, function() {
+ testSlider(settings1);
+ });
+ }
+ }
+ }
+});
diff --git a/__tests__/TestComponents.js b/__tests__/TestComponents.js
new file mode 100644
index 000000000..ebd75589e
--- /dev/null
+++ b/__tests__/TestComponents.js
@@ -0,0 +1,13 @@
+import React from "react";
+import Slider from "../src/index";
+
+export function GenericSliderComponent({ slidesCount, settings }) {
+ const slides = [...Array(slidesCount).keys()].map(item => (
+
)).toBe(true);
- });
-});
diff --git a/__tests__/lazyLoad.test.js b/__tests__/lazyLoad.test.js
new file mode 100644
index 000000000..1ce8491d0
--- /dev/null
+++ b/__tests__/lazyLoad.test.js
@@ -0,0 +1,67 @@
+import { render } from "@testing-library/react";
+import assign from "object-assign";
+import { getRequiredLazySlides } from "../src/utils/innerSliderUtils";
+import {
+ createInnerSliderWrapper,
+ clickNext,
+ clickPrev,
+ tryAllConfigs
+} from "./testUtils";
+
+// const testSettings = settings => {
+// let {container} = createInnerSliderWrapper(settings);
+// for (let click = 0; click < settings.noOfSlides + 2; click++) {
+// let lazyLoadedList = slider.state().lazyLoadedList;
+// let expectedLazyLoadedList = getRequiredLazySlides(
+// assign({}, slider.props(), slider.state())
+// );
+// expectedLazyLoadedList.forEach(slide => {
+// expect(lazyLoadedList.indexOf(slide) >= 0).toEqual(true);
+// });
+// clickNext(slider);
+// }
+
+// slider = createInnerSliderWrapper(settings);
+// for (let click = 0; click < settings.noOfSlides + 2; click++) {
+// let lazyLoadedList = slider.state().lazyLoadedList;
+// let expectedLazyLoadedList = getRequiredLazySlides(
+// assign({}, slider.props(), slider.state())
+// );
+// expectedLazyLoadedList.forEach(slide => {
+// expect(lazyLoadedList.indexOf(slide) >= 0).toEqual(true);
+// });
+// clickPrev(slider);
+// }
+
+// slider = createInnerSliderWrapper(settings);
+// for (let click = 0; click < settings.noOfSlides + 2; click++) {
+// let lazyLoadedList = slider.state().lazyLoadedList;
+// lazyLoadedList.forEach(slideIndex => {
+// expect(
+// slider.find(`[data-index=${slideIndex}]`).props().children !== undefined
+// ).toBe(true);
+// });
+// }
+// };
+
+// describe("LazyLoad test", () => {
+// let settings = {
+// lazyLoad: true,
+// useCSS: false,
+// speed: 0,
+// noOfSlides: [7, 8],
+// initialSlide: [0, 5],
+// slidesToShow: [1, 3, 4],
+// slidesToScroll: [1, 3],
+// centerMode: [true, false]
+// };
+// let settingsList = [];
+// tryAllConfigs(settings, settingsList);
+// // shuffle the list
+// settingsList.sort(() => 0.5 - Math.random());
+// settingsList.forEach((settings, index) => {
+// if (Math.random() < 0.5) {
+// test(`Testing config no. ${index}`, () => testSettings(settings));
+// }
+// });
+// });
diff --git a/__tests__/observations.json b/__tests__/observations.json
new file mode 100644
index 000000000..42e93a7c2
--- /dev/null
+++ b/__tests__/observations.json
@@ -0,0 +1,54 @@
+{
+ "jQueryTest": [
+ {
+ "observation": "Clicks on arrows are not working properly",
+ "possibleCause": "Animation effects are taking effects somehow",
+ "solutions": [
+ {
+ "description": "set useCSS property to false",
+ "status": "did not work"
+ },
+ {
+ "description": "set speed property to 0",
+ "status": "worked, now the clicks are working as of now"
+ }
+ ]
+ },
+ {
+ "observation": "arrows are disabled when slidesToShow are equal to noOfSlides",
+ "status": "causes few tests to fail"
+ },
+ {
+ "observation": "tests are very slow",
+ "possibleCause": "synchronous click event simulation and slow DOM api",
+ "status": "not tried yet"
+ }
+ ],
+ "reactTest": [
+ {
+ "observation": "Clicks on arrows are not working properly",
+ "possibleCause": "Animation effects are taking effects somehow",
+ "solutions": [
+ {
+ "description": "set useCSS property to false",
+ "status": "worked, now the clicks are working as of now"
+ }
+ ]
+ }
+ ],
+ "misc": [
+ {
+ "observation": "In case of reverse scrolling, slick-active class is not being assigned properly.",
+ "example": {
+ "settings": {
+ "noOfSlides": 5,
+ "slidesToShow": 2,
+ "slidesToScroll": 2
+ },
+ "jqueryBehaviour": "after one prev click, current-slide is 5th and active-class is assigned to slide 4th and 5th while the same are displayed in frame",
+ "reactBehaviour": "after one prev click, current-slide is 5th and active-class is assigned to slide 5th and 1st(cloned) while 4th and 5th are displayed in frame",
+ "status": "several tests are failing due to this property"
+ }
+ }
+ ]
+}
diff --git a/__tests__/regression/fix-1813.test.js b/__tests__/regression/fix-1813.test.js
new file mode 100644
index 000000000..9adbcfb7e
--- /dev/null
+++ b/__tests__/regression/fix-1813.test.js
@@ -0,0 +1,164 @@
+//Test fix of #1813: In infinite mode, when slidesToShow equal to the length of slides, infinite functionality is not working.
+// Reversed the fix for #1813 to match the slick carousel functionality. When slides <= slidesToShow, unslick will be activated
+
+import React from "react";
+import { render, fireEvent } from "@testing-library/react";
+
+import {
+ clickNext,
+ clickPrevious,
+ getActiveButton,
+ getActiveSlidesCount,
+ getActiveSlidesText,
+ getButtons,
+ getButtonsLength,
+ getClonesCount,
+ getCurrentSlide,
+ getSlidesCount,
+ hasArrows,
+ hasDots
+} from "../../test-utils";
+import { GenericSliderComponent } from "../TestComponents";
+
+function MultipleItems() {
+ const settings = {
+ dots: true,
+ infinite: true,
+ speed: 500,
+ slidesToShow: 9,
+ slidesToScroll: 3
+ };
+ return ;
+}
+
+describe("Multiple Items with slidesToShow = slides count in infinite mode", function() {
+ it("should have 9 active slides", function() {
+ const { container } = render();
+ expect(getActiveSlidesCount(container)).toEqual(9);
+ });
+ it("should show first 9 slides", function() {
+ const { container } = render();
+ //expect(getActiveButton(container)).toEqual(["1"]);
+ expect(getActiveSlidesText(container)).toEqual([
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9"
+ ]);
+ });
+ it("shouldn't have any arrows", () => {
+ const { container } = render();
+ expect(hasArrows(container)).toEqual(false);
+ });
+ it("shouldn't have any dots", () => {
+ const { container } = render();
+ expect(hasDots(container)).toEqual(false);
+ });
+ // it("should have 0 dots", function() {
+ // const { container } = render();
+ // expect(getButtonsLength(container)).toEqual(0);
+ // });
+ // it("should show slides from 4 when next button is clicked", function() {
+ // const { container } = render();
+ // clickNext(container);
+ // expect(getActiveButton(container)).toEqual(["2"]);
+ // expect(getActiveSlidesText(container)).toEqual([
+ // "4",
+ // "5",
+ // "6",
+ // "7",
+ // "8",
+ // "9",
+ // "1",
+ // "2",
+ // "3"
+ // ]);
+ // });
+ // it("should show slides from 7 when previous button is clicked", function() {
+ // const { container } = render();
+ // clickPrevious(container);
+ // expect(getActiveButton(container)).toEqual(["3"]);
+ // expect(getActiveSlidesText(container)).toEqual([
+ // "7",
+ // "8",
+ // "9",
+ // "1",
+ // "2",
+ // "3",
+ // "4",
+ // "5",
+ // "6"
+ // ]);
+ // });
+ // it("should show slides first 9 slides when first dot is clicked", function() {
+ // const { container } = render();
+ // fireEvent(
+ // getButtons(container)[0],
+ // new MouseEvent("click", {
+ // bubbles: true,
+ // cancelable: true
+ // })
+ // );
+ // expect(getActiveButton(container)).toEqual(["1"]);
+ // expect(getActiveSlidesText(container)).toEqual([
+ // "1",
+ // "2",
+ // "3",
+ // "4",
+ // "5",
+ // "6",
+ // "7",
+ // "8",
+ // "9"
+ // ]);
+ // });
+ // it("should show slides from 4 when middle dot is clicked", function() {
+ // const { container } = render();
+ // fireEvent(
+ // getButtons(container)[1],
+ // new MouseEvent("click", {
+ // bubbles: true,
+ // cancelable: true
+ // })
+ // );
+ // expect(getActiveButton(container)).toEqual(["2"]);
+ // expect(getActiveSlidesText(container)).toEqual([
+ // "4",
+ // "5",
+ // "6",
+ // "7",
+ // "8",
+ // "9",
+ // "1",
+ // "2",
+ // "3"
+ // ]);
+ // });
+ // it("should show slides from 7 when last dot is clicked", function() {
+ // const { container } = render();
+ // fireEvent(
+ // getButtons(container)[2],
+ // new MouseEvent("click", {
+ // bubbles: true,
+ // cancelable: true
+ // })
+ // );
+ // expect(getActiveButton(container)).toEqual(["3"]);
+ // expect(getActiveSlidesText(container)).toEqual([
+ // "7",
+ // "8",
+ // "9",
+ // "1",
+ // "2",
+ // "3",
+ // "4",
+ // "5",
+ // "6"
+ // ]);
+ // });
+});
diff --git a/__tests__/regression/fix-1874.test.js b/__tests__/regression/fix-1874.test.js
new file mode 100644
index 000000000..67f9c1502
--- /dev/null
+++ b/__tests__/regression/fix-1874.test.js
@@ -0,0 +1,25 @@
+// Test fix of#1874: "slick-current" is always on first slide despite initialSlide != 0
+
+import React from "react";
+import { render } from "@testing-library/react";
+
+import { getCurrentSlideContent, clickNext } from "../../test-utils";
+import { GenericSliderComponent } from "../TestComponents";
+
+describe("currentSlide test with different initialSlide values", () => {
+ it("currentSlide is 0 when initialSlide is 0", function() {
+ const { container } = render();
+ expect(getCurrentSlideContent(container)).toEqual("1");
+ clickNext(container);
+ expect(getCurrentSlideContent(container)).toEqual("2");
+ });
+
+ it("currentSlide is 2 when initialSlide is 2", function() {
+ const { container } = render(
+
+ );
+ expect(getCurrentSlideContent(container)).toEqual("3");
+ clickNext(container);
+ expect(getCurrentSlideContent(container)).toEqual("4");
+ });
+});
diff --git a/__tests__/regression/fix-2315.test.js b/__tests__/regression/fix-2315.test.js
new file mode 100644
index 000000000..0be8f43f6
--- /dev/null
+++ b/__tests__/regression/fix-2315.test.js
@@ -0,0 +1,35 @@
+// Test fix of #2315: Slider crashing after a state change in parent component
+import React from "react";
+import { render, fireEvent } from "@testing-library/react";
+
+import { getCurrentSlideContent, getSlidesCount } from "../../test-utils";
+import { GenericSliderComponent } from "../TestComponents";
+
+function TestSlider() {
+ const [count, setCount] = React.useState();
+
+ return (
+
+
+
+
+ );
+}
+
+describe("State change in parent component of slider", () => {
+ it("Slider shoud work afer clicking on Increment button", function() {
+ const { container } = render();
+ fireEvent(
+ container.getElementsByClassName("increment-button")[0],
+ new MouseEvent("click", {
+ bubbles: true,
+ cancelable: true
+ })
+ );
+ // Throws an error "Maximum update depth exceeded." if the bug exists
+ expect(getCurrentSlideContent(container)).toEqual("1");
+ expect(getSlidesCount(container)).toEqual(8);
+ });
+});
diff --git a/__tests__/regression/fix-2414.test.js b/__tests__/regression/fix-2414.test.js
new file mode 100644
index 000000000..41413c72c
--- /dev/null
+++ b/__tests__/regression/fix-2414.test.js
@@ -0,0 +1,62 @@
+// Test fix of #2414: Extra clones in infinite mode when there is only one slide or unslick is true
+import React from "react";
+import { render, fireEvent } from "@testing-library/react";
+
+import {
+ getCurrentSlideContent,
+ getSlidesCount,
+ getActiveSlidesCount,
+ getClonesCount,
+ hasArrows,
+ hasDots
+} from "../../test-utils";
+import { GenericSliderComponent } from "../TestComponents";
+
+function SliderWithOneSlide() {
+ const settings = {
+ dots: true,
+ infinite: true
+ };
+ return ;
+}
+
+function SliderWithUnslick() {
+ const settings = {
+ dots: true,
+ infinite: true,
+ unslick: true
+ };
+ return ;
+}
+
+describe("Slider with one slide", function() {
+ it("should have 1 active slide", function() {
+ const { container } = render();
+ expect(getActiveSlidesCount(container)).toEqual(1);
+ });
+ it("should not have any clones", function() {
+ const { container } = render();
+ expect(getClonesCount(container)).toEqual(0);
+ });
+ it("should no have dots and arrows", function() {
+ const { container } = render();
+ expect(hasArrows(container)).toEqual(false);
+ expect(hasDots(container)).toEqual(false);
+ });
+});
+
+describe("Slider with unslick=true", function() {
+ it("should have one active slide", function() {
+ const { container } = render();
+ expect(getActiveSlidesCount(container)).toEqual(1);
+ });
+ it("should not have any clones", function() {
+ const { container } = render();
+ expect(getClonesCount(container)).toEqual(0);
+ });
+ it("should no have dots and arrows", function() {
+ const { container } = render();
+ expect(hasArrows(container)).toEqual(false);
+ expect(hasDots(container)).toEqual(false);
+ });
+});
diff --git a/__tests__/sample.js b/__tests__/sample.js
deleted file mode 100644
index 98d2e6516..000000000
--- a/__tests__/sample.js
+++ /dev/null
@@ -1,20 +0,0 @@
-'use strict';
-import React from 'react';
-import {shallow, mount} from 'enzyme';
-import Slider from '../src/index';
-
-
-
-describe('basic test', function() {
- it('should add numbers', function() {
- expect(2 + 2).toBe(4);
- });
-});
-
-describe('sample enzyme test', function() {
- it('should render', function() {
- const wrapper = shallow(
slide1
);
- expect(wrapper.contains(
slide1
)).toBe(true);
- });
-});
-
diff --git a/__tests__/sliderStyles.test.js b/__tests__/sliderStyles.test.js
new file mode 100644
index 000000000..46167d56f
--- /dev/null
+++ b/__tests__/sliderStyles.test.js
@@ -0,0 +1,44 @@
+import assign from "object-assign";
+import { getRequiredLazySlides } from "../src/utils/innerSliderUtils";
+import {
+ createInnerSliderWrapper,
+ clickNext,
+ clickPrev,
+ tryAllConfigs,
+ actualTrackLeft,
+ testTrackLeft
+} from "./testUtils";
+import { getTrackLeft } from "../src/utils/innerSliderUtils";
+
+const testSettings = settings => {
+ let slider = createInnerSliderWrapper(settings);
+ for (let click = 0; click < settings.noOfSlides + 2; click++) {
+ testTrackLeft(slider);
+ clickNext(slider);
+ }
+ slider = createInnerSliderWrapper(settings);
+ for (let click = 0; click < settings.noOfSlides + 2; click++) {
+ testTrackLeft(slider);
+ clickPrev(slider);
+ }
+};
+
+describe("Slider Styles Tests", () => {
+ let settings = {
+ useCSS: false,
+ speed: 0,
+ centerMode: [true, false],
+ noOfSlides: [7, 8],
+ initialSlide: [0, 5],
+ slidesToShow: [1, 3, 4]
+ };
+ let settingsList = [];
+ tryAllConfigs(settings, settingsList);
+ // shuffle the list
+ settingsList.sort(() => 0.5 - Math.random());
+ settingsList.forEach((settings, index) => {
+ // if (Math.random() < 0.5) {
+ // test(`Testing config no. ${index}`, () => testSettings(settings));
+ // }
+ });
+});
diff --git a/__tests__/testUtils.js b/__tests__/testUtils.js
new file mode 100644
index 000000000..9778d34f4
--- /dev/null
+++ b/__tests__/testUtils.js
@@ -0,0 +1,174 @@
+import React from "react";
+import $ from "jquery";
+import assign from "object-assign";
+import { render } from "@testing-library/react";
+import Slider from "../src/slider";
+import { InnerSlider } from "../src/inner-slider";
+import defaultProps from "../src/default-props";
+import * as slickCarousel from "slick-carousel"; // defining slick in global environment
+import { getTrackLeft } from "../src/utils/innerSliderUtils";
+import {
+ getActiveSlides,
+ getActiveSlidesCount,
+ clickNext,
+ clickPrevious
+} from "../test-utils";
+
+// finds active slide number in the last transition in the forward direction
+export function activeSlideInLastTransition(
+ noOfSlides,
+ slidesToShow,
+ slidesToScroll
+) {
+ let currentSlide = 0;
+ while (currentSlide < noOfSlides) {
+ currentSlide += slidesToScroll;
+ }
+ return currentSlide - slidesToScroll;
+}
+
+// create jsx-form children for react slider
+export function createReactSliderChildren(noOfSlides) {
+ return Array.from(Array(noOfSlides).keys()).map(i => (
+
+
{i + 1}
+
+ ));
+}
+
+// create a react-slider with given noOfSlides and other props
+// variable widths are ignored for now for simplicity
+export function createReactSlider({ noOfSlides, ...props }) {
+ return {createReactSliderChildren(noOfSlides)};
+}
+
+// create a react inner-slider with given noOfSlides and other props
+// performs most operations like the ones when mounted inside Slider component
+export function createInnerSlider({ noOfSlides, ...settings }) {
+ if (settings.centerMode) {
+ settings.slidesToScroll = 1; // always scroll by one when centerMode is enabled
+ }
+ settings = assign({}, defaultProps, settings);
+ const children = React.Children.toArray(
+ createReactSliderChildren(noOfSlides)
+ );
+ return {children};
+}
+
+export function createInnerSliderWrapper(settings) {
+ return render(createInnerSlider(settings)).container;
+}
+
+// creates a dom string, containing children of slick children
+export function createJQuerySliderChildren(noOfSlides) {
+ let children = [];
+ for (let i = 0; i < noOfSlides; i++) {
+ children.push(`
${i + 1}
`);
+ }
+ return children.join("");
+}
+
+// performs the very basic tests while clicking next or prev
+export function testSliderScroll({ direction, ...settings }) {
+ const { noOfSlides, slidesToShow, slidesToScroll, initialSlide } = settings;
+ // initialize react slider
+ const { container } = render(createReactSlider(settings));
+ // initialize jquery slider
+ document.body.innerHTML = `
+
+ ${createJQuerySliderChildren(noOfSlides)}
+
+ `;
+ $(".regular.slider").slick({
+ ...settings
+ });
+ // console.log('setings:', settings)
+
+ let expectedSlideIndex = initialSlide || 0;
+ for (let click = 0; click < 2 * noOfSlides + 2; click++) {
+ let activeslides = getActiveSlides(container);
+ let $activeSlides = $(".regular.slider").find("div.slick-active");
+ expect(getActiveSlidesCount(container)).toEqual(slidesToShow || 1);
+ expect($activeSlides.length).toEqual(slidesToShow || 1);
+ let firstActiveSlide = activeslides[0];
+ let $firstActiveSlide = $activeSlides.first();
+ // console.log('classes', $firstActiveSlide.attr('data-slick-index'))
+ // console.warn('currentSlide:', firstActiveSlide.prop('data-index'), 'expected slide', expectedSlideIndex)
+ expect(parseInt(firstActiveSlide.getAttribute("data-index"))).toEqual(
+ expectedSlideIndex % noOfSlides
+ );
+ expect(parseInt($firstActiveSlide.attr("data-slick-index"))).toEqual(
+ expectedSlideIndex % noOfSlides
+ );
+ if (direction === "next") {
+ // click the next arrow button
+ clickNext(container);
+ $("button.slick-next").click();
+ expectedSlideIndex += slidesToScroll || 1;
+ if (expectedSlideIndex >= noOfSlides) {
+ expectedSlideIndex = 0;
+ }
+ } else {
+ // click on the prev arrow button
+ clickPrevious(container);
+ $("button.slick-prev").click();
+ expectedSlideIndex -= slidesToScroll || 1;
+ if (expectedSlideIndex < 0) {
+ expectedSlideIndex = activeSlideInLastTransition(
+ noOfSlides,
+ slidesToShow,
+ slidesToScroll
+ );
+ }
+ }
+ }
+}
+
+// function to run tests on a slider,
+// scrolls slider to the right by clicking right arrow several times
+// scrolls slider to the left by clicking left arrow several times
+export function testSlider(settings) {
+ const settings1 = { direction: "next", ...settings };
+ const settings2 = { direction: "prev", ...settings };
+ testSliderScroll(settings1);
+ testSliderScroll(settings2);
+}
+
+export const tryAllConfigs = (settings, settingsList) => {
+ let leaf = true;
+ for (let key of Object.keys(settings)) {
+ if (Array.isArray(settings[key])) {
+ leaf = false;
+ for (let val of settings[key]) {
+ tryAllConfigs({ ...settings, [key]: val }, settingsList);
+ }
+ }
+ }
+ if (leaf) {
+ if (
+ settingsList
+ .map(setting => JSON.stringify(setting))
+ .indexOf(JSON.stringify(settings)) < 0
+ ) {
+ settingsList.push(settings);
+ }
+ }
+};
+
+export const actualTrackLeft = container =>
+ container
+ .querySelector(".slick-track")
+ .style.transform.match(/translate3d\((\d+)px/i)[1];
+
+export const testTrackLeft = container => {
+ let trackLeft = parseInt(actualTrackLeft(container));
+ let spec = assign({}, wrapper.props(), wrapper.state(), {
+ slideIndex: wrapper.state().currentSlide,
+ trackRef: null
+ });
+ let expectedTrackLeft = getTrackLeft(spec);
+ expect(trackLeft).toEqual(parseInt(expectedTrackLeft));
+};
+test("fake test", () => {
+ expect(1).toBe(1);
+});
diff --git a/__tests__/utils/filterSettings.test.js b/__tests__/utils/filterSettings.test.js
new file mode 100644
index 000000000..fa431b195
--- /dev/null
+++ b/__tests__/utils/filterSettings.test.js
@@ -0,0 +1,18 @@
+import { filterSettings } from "../../src/utils/innerSliderUtils";
+
+describe("filterSettings", () => {
+ it("returns empty object if there are no valid settings", () => {
+ expect(filterSettings({})).toEqual({});
+ expect(filterSettings({ age: 10 })).toEqual({});
+ });
+ it("return an object with valid settings and omits extra properties", () => {
+ expect(filterSettings({ arrows: true, dots: true })).toEqual({
+ arrows: true,
+ dots: true
+ });
+ expect(filterSettings({ arrows: true, dots: true, age: 10 })).toEqual({
+ arrows: true,
+ dots: true
+ });
+ });
+});
diff --git a/bower.json b/bower.json
deleted file mode 100644
index 883f089e3..000000000
--- a/bower.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "react-slick",
- "main": "dist/react-slick.min.js",
- "version": "0.14.2",
- "homepage": "https://github.com/akiran/react-slick",
- "authors": [
- "Kiran Abburi"
- ],
- "license": "MIT",
- "ignore": [
- "**/.*",
- "node_modules",
- "bower_components",
- "test",
- "tests"
- ],
- "dependencies": {
- "slick-carousel": "~1.6.0"
- },
- "devDependencies": {
- "react": "~0.12.1",
- "jquery": "~2.1.1",
- "should": "~4.3.0",
- "foundation-apps": "~1.0.2"
- }
-}
diff --git a/docs/api.md b/docs/api.md
new file mode 100644
index 000000000..bcb710faa
--- /dev/null
+++ b/docs/api.md
@@ -0,0 +1,23 @@
+### Methods
+
+| Name | Arguments | Description |
+| ------------ | ------------------ | --------------------------- |
+| `slickPrev` | None | go to previous slide |
+| `slickNext` | None | go to next slide |
+| `slickGoTo` | index, dontAnimate | go to the given slide index |
+| `slickPause` | None | pause the autoplay |
+| `slickPlay` | None | start the autoplay |
+
+#### Followings are not going to be implemented
+
+| Name | type | Reason |
+| ------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `unslick` | method | same functionality can be achieved with `unslick` prop |
+| `slickSetOption` | method | same functionality can be achieved via props and managing state for them in wrapper |
+| `slickFilter` | method | same functionality can be achieved as with dynamic slides, look at dynamic slides [example](https://github.com/akiran/react-slick/blob/master/examples/DynamicSlides.js) |
+| `slickUnfilter` | method | same functionality can be achieved as with dynamic slides, look at dynamic slides [example](https://github.com/akiran/react-slick/blob/master/examples/DynamicSlides.js) |
+| `slickAdd` | method | same functionality can be achieved as with dynamic slides, look at dynamic slides [example](https://github.com/akiran/react-slick/blob/master/examples/DynamicSlides.js) |
+| `slickRemove` | method | same functionality can be achieved as with dynamic slides, look at dynamic slides [example](https://github.com/akiran/react-slick/blob/master/examples/DynamicSlides.js) |
+| `slickCurrentSlide` | method | same functionality can be achieved with `beforeChange hook` |
+| `slickGetOption` | method | manage wrapper state for desired options |
+| `getSlick` | method | a simple ref will do |
diff --git a/docs/common.md b/docs/common.md
new file mode 100644
index 000000000..1b736ea42
--- /dev/null
+++ b/docs/common.md
@@ -0,0 +1,66 @@
+#### `responsive` property
+
+Array of objects in the form of `{ breakpoint: int, settings: { ... } }` The breakpoint _int_ is the `maxWidth` so the settings will be applied when resolution is below this value. Breakpoints in the array should be ordered from smallest to greatest. Use 'unslick' in place of the settings object to disable rendering the carousel at that breakpoint. Example: `[ { breakpoint: 768, settings: { slidesToShow: 3 } }, { breakpoint: 1024, settings: { slidesToShow: 5 } }, { breakpoint: 100000, settings: 'unslick' } ]`
+
+### Custom next/prev arrows
+
+To customize the next/prev arrow elements, simply create new React components and set them
+as the values of nextArrow and prevArrow.
+
+```js
+class LeftNavButton extends React.Component {
+ render() {
+ return ;
+ }
+}
+```
+
+Important: be sure that you pass your component's props to your clickable element
+like the example above. If you don't, your custom component won't trigger the click handler.
+
+You can also set `onClick={this.props.onClick}` if you only want to set the click handler.
+
+### Flexbox support
+
+If you have flex property on container div of slider, add below css
+
+```css
+* {
+ min-height: 0;
+ min-width: 0;
+}
+```
+
+### Test Setup
+
+If you try to run tests with jest in a project that uses react-slick, you may run into this error
+
+```
+matchMedia not present, legacy browsers require a polyfill
+```
+
+To fix this issue add below snippet in test-setup.js
+
+```js
+window.matchMedia =
+ window.matchMedia ||
+ function() {
+ return {
+ matches: false,
+ addListener: function() {},
+ removeListener: function() {}
+ };
+ };
+```
+
+and add below jest config in package.json
+
+```json
+"jest": {
+ "setupFiles": ["test-setup.js"]
+}
+```
+
+### Polyfills for old IE support
+
+`matchMedia` support from [media-match](https://github.com/weblinc/media-match)
diff --git a/docs/demos.js b/docs/demos.js
new file mode 100644
index 000000000..a03cf825b
--- /dev/null
+++ b/docs/demos.js
@@ -0,0 +1,72 @@
+"use strict";
+
+import React from "react";
+import Slider from "../src/slider";
+
+import SimpleSlider from "../examples/SimpleSlider";
+import SlideChangeHooks from "../examples/SlideChangeHooks";
+import MultipleItems from "../examples/MultipleItems";
+import MultipleRows from "../examples/MultipleRows";
+import Responsive from "../examples/Responsive";
+import Resizable from "../examples/Resizable";
+import UnevenSetsInfinite from "../examples/UnevenSetsInfinite";
+import UnevenSetsFinite from "../examples/UnevenSetsFinite";
+import CenterMode from "../examples/CenterMode";
+import FocusOnSelect from "../examples/FocusOnSelect";
+import AutoPlay from "../examples/AutoPlay";
+import AutoPlayMethods from "../examples/AutoPlayMethods";
+import PauseOnHover from "../examples/PauseOnHover";
+import Rtl from "../examples/Rtl";
+import VariableWidth from "../examples/VariableWidth";
+import AdaptiveHeight from "../examples/AdaptiveHeight";
+import LazyLoad from "../examples/LazyLoad";
+import Fade from "../examples/Fade";
+import SlickGoTo from "../examples/SlickGoTo";
+import CustomArrows from "../examples/CustomArrows";
+import PreviousNextMethods from "../examples/PreviousNextMethods";
+import DynamicSlides from "../examples/DynamicSlides";
+import VerticalMode from "../examples/VerticalMode";
+import SwipeToSlide from "../examples/SwipeToSlide";
+import VerticalSwipeToSlide from "../examples/VerticalSwipeToSlide";
+import CustomPaging from "../examples/CustomPaging";
+import CustomSlides from "../examples/CustomSlides";
+import AsNavFor from "../examples/AsNavFor";
+import AppendDots from "../examples/AppendDots";
+
+export default class App extends React.Component {
+ render() {
+ return (
+
+
+ );
+}
diff --git a/playwright-tests/sample/sample.spec.tsx b/playwright-tests/sample/sample.spec.tsx
new file mode 100644
index 000000000..04d888e9d
--- /dev/null
+++ b/playwright-tests/sample/sample.spec.tsx
@@ -0,0 +1,15 @@
+//Imports the test and expect functions from the Playwright ct-react module
+import { test, expect } from "@playwright/experimental-ct-react";
+//Imports the App component to test from the relative ../App path
+import App from "./sample.story";
+
+//Configures the viewport to a 500x500 size
+test.use({ viewport: { width: 500, height: 500 } });
+//Starts a test case named "should work" which will run asynchronously,
+//mount function binding is destructured from test parameter
+test("Sample playwright test", async ({ mount }) => {
+ //Uses mount() to instantiate the component in isolation
+ const component = await mount();
+ //Asserts that component contains expected "Learn React" text on it verifying basic render.
+ await expect(component).toContainText("Learn React");
+});
diff --git a/playwright-tests/sample/sample.story.tsx b/playwright-tests/sample/sample.story.tsx
new file mode 100644
index 000000000..1d3aef811
--- /dev/null
+++ b/playwright-tests/sample/sample.story.tsx
@@ -0,0 +1,5 @@
+import React from "react";
+
+export default function App() {
+ return