+ {/* Render Slider */}
+
+
+
+
+
+ {/* Render Navigation */}
+ {showNavs && images.length > 0 && slideIdx > 0 && (
+
+ )}
+ {showNavs && images.length > 0 && slideIdx < images.length - 1 && (
+
+ )}
+
+ {/* Render Bullets */}
+ {showBullets && images.length > 0 && (
+
+ {Array.from(Array(images.length).keys()).map((e) => (
+ ))
+ }
+
+ )}
+
+
+ );
+};
+
+export default SimpleImageSlider;
diff --git a/src/ImageSliderData.js b/src/ImageSliderData.js
deleted file mode 100644
index 47bfcf6..0000000
--- a/src/ImageSliderData.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import ImageNavArrowLeft1 from "./images/arrow-left-1.png";
-import ImageNavArrowLeft2 from "./images/arrow-left-2.png";
-import ImageNavArrowRight1 from "./images/arrow-right-1.png";
-import ImageNavArrowRight2 from "./images/arrow-right-2.png";
-
-const AltNavArrowLeft = "slide to left";
-const AltNavArrowRight = "slide to right";
-
-const ClassNameRoot = "image-slider";
-const ClassNameNavs = `${ClassNameRoot}-navs`;
-const ClassNameBullets = `${ClassNameRoot}-bullets`;
-
-export default {
- ClassNameRoot,
- ClassNameNavs,
- ClassNameBullets,
- ImageNavArrowLeft1,
- ImageNavArrowLeft2,
- ImageNavArrowRight1,
- ImageNavArrowRight2,
- AltNavArrowLeft,
- AltNavArrowRight,
-};
diff --git a/src/ImageSliderNavigation.tsx b/src/ImageSliderNavigation.tsx
new file mode 100644
index 0000000..d154776
--- /dev/null
+++ b/src/ImageSliderNavigation.tsx
@@ -0,0 +1,48 @@
+import React from "react";
+import styles from "./ImageSliderStyle";
+import ImageNavArrowLeft1 from "./images/arrow-left-1.png";
+import ImageNavArrowLeft2 from "./images/arrow-left-2.png";
+import ImageNavArrowRight1 from "./images/arrow-right-1.png";
+import ImageNavArrowRight2 from "./images/arrow-right-2.png";
+
+export enum ImageSliderNavStyle {
+ NORMAL = 1,
+ BOLD = 2
+}
+
+export enum ImageSliderNavDirection {
+ LEFT = 'left',
+ RIGHT = 'right'
+}
+
+type ImageSliderNavigationProps = {
+ navStyle: ImageSliderNavStyle;
+ direction: ImageSliderNavDirection;
+ onClickNav: (direction: ImageSliderNavDirection) => (event: React.SyntheticEvent
) => void;
+};
+
+const altNavArrowLeft = "slide to left";
+const altNavArrowRight = "slide to right";
+const images: { [key: string]: string } = {
+ [`image-${ImageSliderNavDirection.LEFT}-${ImageSliderNavStyle.NORMAL}`]: ImageNavArrowLeft1,
+ [`image-${ImageSliderNavDirection.RIGHT}-${ImageSliderNavStyle.NORMAL}`]: ImageNavArrowRight1,
+ [`image-${ImageSliderNavDirection.LEFT}-${ImageSliderNavStyle.BOLD}`]: ImageNavArrowLeft2,
+ [`image-${ImageSliderNavDirection.RIGHT}-${ImageSliderNavStyle.BOLD}`]: ImageNavArrowRight2
+};
+
+const ImageSliderNavigation: React.FC = (props: ImageSliderNavigationProps) => {
+ return (
+
+ )
+};
+
+export default ImageSliderNavigation;
\ No newline at end of file
diff --git a/src/ImageSliderPreLoader.js b/src/ImageSliderPreLoader.js
deleted file mode 100644
index 0fabff0..0000000
--- a/src/ImageSliderPreLoader.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const ImageSliderPreLoader = (() => {
- const loadedUrl = {};
- const loadQueue = [];
- const loaderCount = 3;
- const loaderPool = new Array(loaderCount).fill(0).map(e => new Image());
-
- return {
- load: (url) => {
- if (!url || loadedUrl[url]) {
- return;
- }
-
- if (loaderPool.length === 0) {
- loadQueue.push(url);
- } else {
- const imageLoader = loaderPool.shift();
-
- imageLoader.src = url;
- imageLoader.onload = () => {
- loadedUrl[url] = true;
- if (loadQueue.length > 0) {
- imageLoader.src = loadQueue.shift();
- } else {
- loaderPool.push(imageLoader);
- }
- };
- }
- },
- };
-})();
-
-export default ImageSliderPreLoader;
diff --git a/src/ImageSliderPreLoader.ts b/src/ImageSliderPreLoader.ts
new file mode 100644
index 0000000..f16f65c
--- /dev/null
+++ b/src/ImageSliderPreLoader.ts
@@ -0,0 +1,32 @@
+const ImageSliderPreLoader = (() => {
+ const loadedUrl: { [key: string]: boolean } = {};
+ const loadQueue: Array = [];
+ const loaderCount = 3;
+ const loaderPool: Array = new Array(loaderCount).fill(0).map(() => new Image());
+
+ return {
+ load: (url: string) => {
+ if (!url || loadedUrl[url]) {
+ return;
+ }
+
+ if (loaderPool.length === 0) {
+ loadQueue.push(url);
+ } else {
+ const imageLoader: HTMLImageElement = loaderPool.shift() as HTMLImageElement;
+
+ imageLoader.src = url;
+ imageLoader.onload = () => {
+ loadedUrl[url] = true;
+ if (loadQueue.length > 0) {
+ imageLoader.src = loadQueue.shift() as string;
+ } else {
+ loaderPool.push(imageLoader);
+ }
+ };
+ }
+ }
+ };
+})();
+
+export default ImageSliderPreLoader;
diff --git a/src/ImageSliderPropTypes.js b/src/ImageSliderPropTypes.js
deleted file mode 100644
index 81d4275..0000000
--- a/src/ImageSliderPropTypes.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import PropTypes from "prop-types";
-
-const isValidNavStyle = prop => (/[1-2]/.test(prop) && typeof (prop) === "number");
-
-export default {
- propTypes: {
- // Required
- width: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.number,
- ]).isRequired,
- height: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.number,
- ]).isRequired,
- images: PropTypes.arrayOf(PropTypes.shape({
- url: PropTypes.string.isRequired,
- })).isRequired,
-
- // Optional
- style: PropTypes.objectOf(PropTypes.string),
- slideDuration: PropTypes.number,
- showNavs: PropTypes.bool,
- showBullets: PropTypes.bool,
- bgColor: PropTypes.string,
- useGPURender: PropTypes.bool,
- onClick: PropTypes.func,
- onClickNav: PropTypes.func,
- onClickBullets: PropTypes.func,
- onStartSlide: PropTypes.func,
- onCompleteSlide: PropTypes.func,
-
- // Optional, Navigation Arrow Style
- navStyle: (props, propName, componentName) => {
- if (!isValidNavStyle(props[propName])) {
- return new Error(`Invalid prop ${propName} supplied to ${componentName}. Validation failed.`);
- }
- return null;
- },
- },
- defaultTypes: {
- slideDuration: 0.5,
- showNavs: true,
- showBullets: true,
- bgColor: "#000000",
- useGPURender: true,
- navStyle: 1,
- },
-};
diff --git a/src/ImageSliderStyle.js b/src/ImageSliderStyle.js
deleted file mode 100644
index df7e7a0..0000000
--- a/src/ImageSliderStyle.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import { assignObjects } from "./ImageSliderUtil";
-
-const basic = {
- display: "block",
- margin: "0",
- padding: "0",
- border: "0",
-};
-const basicRootContainer = {
- position: "absolute",
- left: 0,
- top: 0,
- width: "100%",
- height: "100%",
-};
-const basicSlide = {
- position: "absolute",
- left: 0,
- top: 0,
- width: "100%",
- height: "100%",
- backgroundSize: "cover",
-};
-const basicNav = {
- position: "absolute",
- top: "50%",
- cursor: "pointer",
- outline: "none",
- background: "none",
-};
-const bulletContainer = {
- position: "absolute",
- left: "50%",
- bottom: "15px",
-};
-const bulletSize = 15;
-const bulletMargin = 3;
-const basicBullet = {
- display: "inline-block",
- cursor: "pointer",
- outline: "none",
- background: "none",
- boxShadow: "1px 1px 1px 0px #1a1a1a",
- borderRadius: "50%",
- border: "1px solid #FFFFFF",
- width: `${bulletSize}px`,
- height: `${bulletSize}px`,
- marginLeft: `${bulletMargin}px`,
- marginRight: `${bulletMargin}px`,
-};
-
-export default {
- ImageSlider: assignObjects(basic, basicRootContainer),
- ImageSlideCurrent: assignObjects(basicSlide, { overflow: "hidden" }),
- ImageSlideNext: assignObjects(basicSlide, { overflow: "hidden" }),
- NavLeft: assignObjects(basic, basicNav, { left: "30px", marginTop: "-25px" }),
- NavRight: assignObjects(basic, basicNav, { right: "30px", marginTop: "-25px" }),
- BulletContainer: bulletLength => assignObjects(basic, bulletContainer, { marginLeft: `-${bulletLength * (bulletSize + bulletMargin * 2) / 2}px` }),
- BulletNormal: assignObjects(basic, basicBullet),
- BulletActive: assignObjects(basic, basicBullet, { background: "#FFFFFF" }),
-
- // methods
- getRootContainer: (width, height, bgColor) => assignObjects(basic, {
- overflow: "hidden",
- width,
- height,
- background: bgColor,
- }),
- getSubContainer: (width, height) => assignObjects(basic, {
- position: "absolute",
- overflow: "hidden",
- width,
- height,
- }),
- getImageSlide: (url, duration, idx, isGpuRender) => assignObjects(basicSlide, {
- overflow: "hidden",
- transition: `${duration}s`,
- backgroundImage: `url(${url})`,
- transform: isGpuRender ? `translate3d(${idx * 100}%, 0px, 0px)` : `translate(${idx * 100}%, 0px)`,
- }),
-};
diff --git a/src/ImageSliderStyle.ts b/src/ImageSliderStyle.ts
new file mode 100644
index 0000000..6271990
--- /dev/null
+++ b/src/ImageSliderStyle.ts
@@ -0,0 +1,81 @@
+const basic = {
+ display: "block",
+ margin: "0",
+ padding: "0",
+ border: "0",
+};
+const basicRootContainer = {
+ position: "absolute",
+ left: 0,
+ top: 0,
+ width: "100%",
+ height: "100%",
+};
+const basicSlide = {
+ position: "absolute",
+ left: 0,
+ top: 0,
+ width: "100%",
+ height: "100%",
+ backgroundSize: "cover",
+};
+const basicNav = {
+ position: "absolute",
+ top: "50%",
+ cursor: "pointer",
+ outline: "none",
+ background: "none",
+};
+const bulletContainer = {
+ position: "absolute",
+ left: "50%",
+ bottom: "15px",
+};
+const bulletSize = 15;
+const bulletMargin = 3;
+const basicBullet = {
+ display: "inline-block",
+ cursor: "pointer",
+ outline: "none",
+ background: "none",
+ boxShadow: "1px 1px 1px 0px #1a1a1a",
+ borderRadius: "50%",
+ border: "1px solid #FFFFFF",
+ width: `${bulletSize}px`,
+ height: `${bulletSize}px`,
+ marginLeft: `${bulletMargin}px`,
+ marginRight: `${bulletMargin}px`,
+};
+
+export default {
+ ImageSlider: { ...basic, ...basicRootContainer } as React.CSSProperties,
+ ImageSlideCurrent: { ...basicSlide, overflow: "hidden" } as React.CSSProperties,
+ ImageSlideNext: { ...basicSlide, overflow: "hidden" } as React.CSSProperties,
+ NavLeft: { ...basic, ...basicNav, left: "30px", marginTop: "-25px" } as React.CSSProperties,
+ NavRight: { ...basic, ...basicNav, right: "30px", marginTop: "-25px" } as React.CSSProperties,
+ BulletNormal: { ...basic, ...basicBullet } as React.CSSProperties,
+ BulletActive: { ...basic, ...basicBullet, background: "#FFF" } as React.CSSProperties,
+
+ getRootContainer: (width: number | string, height: number | string, backgroundColor: string): React.CSSProperties => ({ ...basic,
+ overflow: "hidden",
+ width,
+ height,
+ backgroundColor,
+ }) as React.CSSProperties,
+ getSubContainer: (width: number | string, height: number | string): React.CSSProperties => ({ ...basic,
+ position: "absolute",
+ overflow: "hidden",
+ width,
+ height,
+ }) as React.CSSProperties,
+ getBulletContainer: (bulletLength: number): React.CSSProperties => ({ ...basic,
+ ...bulletContainer,
+ marginLeft: `-${bulletLength * (bulletSize + bulletMargin * 2) / 2}px`
+ }) as React.CSSProperties,
+ getImageSlide: (url: string, duration: number, idx: number, isGpuRender: boolean): React.CSSProperties => ({ ...basicSlide,
+ overflow: "hidden",
+ transition: `${duration}s`,
+ backgroundImage: `url(${url})`,
+ transform: isGpuRender ? `translate3d(${idx * 100}%, 0px, 0px)` : `translate(${idx * 100}%, 0px)`,
+ }) as React.CSSProperties,
+};
diff --git a/src/ImageSliderUtil.js b/src/ImageSliderUtil.js
deleted file mode 100644
index b8057fc..0000000
--- a/src/ImageSliderUtil.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * @description Assign multiple objects.
- * @param {...object} object - multiple objects.
- * @return {object} assigned object.
- */
-export const assignObjects = (...args) => Object.assign({}, ...args);
\ No newline at end of file
diff --git a/src/global.d.ts b/src/global.d.ts
new file mode 100644
index 0000000..9d3137d
--- /dev/null
+++ b/src/global.d.ts
@@ -0,0 +1,4 @@
+declare module '*.png' {
+ const value: string;
+ export = value;
+}
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..5d91df2
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,3 @@
+import ImageSlider from './ImageSlider';
+
+export default ImageSlider;
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..1072158
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,30 @@
+{
+ "compilerOptions": {
+ "declaration": true,
+ "declarationDir": "./dist",
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "node",
+ "esModuleInterop": true,
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "alwaysStrict": true,
+ "strictNullChecks": true,
+ "strictPropertyInitialization": true,
+ "noImplicitReturns": true,
+ "noUnusedParameters": true,
+ "allowSyntheticDefaultImports": true,
+
+ "jsx": "react",
+ "types": ["react"],
+ "rootDir": "src",
+ "outDir": "dist",
+ },
+ "include": [
+ "src/**/*",
+ "example/*"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/webpack.config.js b/webpack.config.js
index a73f9a5..1aab5f3 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -2,7 +2,7 @@ const path = require("path");
module.exports = {
entry: {
- index: ["@babel/polyfill", "./example/App.jsx"],
+ index: ["./example/App.jsx"],
},
output: {
filename: "[name].js",
@@ -20,6 +20,8 @@ module.exports = {
],
devServer: {
contentBase: "./example",
- host: "0.0.0.0",
+ host: "localhost",
+ inline: true,
+ open: true
},
};