diff --git a/.fatherrc.ts b/.fatherrc.ts
new file mode 100644
index 0000000..6099e01
--- /dev/null
+++ b/.fatherrc.ts
@@ -0,0 +1,7 @@
+export default {
+ esm: 'babel',
+ cjs: 'babel',
+ extractCSS: true,
+ lessInBabelMode: true,
+ runtimeHelpers: true,
+};
diff --git a/.gitignore b/.gitignore
index bee1cf6..82cff45 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,12 +9,17 @@
# production
/dist
+/docs-dist
# misc
.DS_Store
# umi
-/src/.umi
-/src/.umi-production
-/src/.umi-test
-/.env.local
+.umi
+.umi-production
+.umi-test
+.env.local
+
+# ide
+/.vscode
+/.idea
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..0ce6ea0
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+registry = "https://registry.npmjs.com/"
diff --git a/.prettierignore b/.prettierignore
index 0d4222f..ecb24d3 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,4 +1,3 @@
-**/*.md
**/*.svg
**/*.ejs
**/*.html
diff --git a/.umirc.ts b/.umirc.ts
index 6fb25c9..2d4a0f7 100644
--- a/.umirc.ts
+++ b/.umirc.ts
@@ -1,9 +1,11 @@
-import { defineConfig } from 'umi';
+import { defineConfig } from 'dumi';
export default defineConfig({
- nodeModulesTransform: {
- type: 'none',
- },
- routes: [{ path: '/', component: '@/pages/index' }],
- fastRefresh: {},
+ title: 'slider-vertify',
+ favicon: 'http://h5.dooring.cn/uploads/logo_1742fd359da.png',
+ logo: 'http://h5.dooring.cn/uploads/logo_1742fd359da.png',
+ outputPath: '../dooring-bs/server/static/slider-vertify',
+ base: '/slider-vertify/',
+ publicPath: '/slider-vertify/',
+ // more config: https://d.umijs.org/config
});
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 6f10353..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2021 MrXujiang
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..798887b
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,27 @@
+## Hello react-slider-vertify!
+
+react-slider-vertify 是一款前端实现的滑动验证码组件, 我们可以通过它轻松的控制验证的整个生命周期(刷新时, 验证成功时, 验证失败时的回调), 并拥有一定的配置化能力.
+
+
+
+### More Production
+
+| name | Description |
+| --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
+| [H5-Dooring](https://github.com/MrXujiang/h5-Dooring) | 让 H5 制作像搭积木一样简单, 轻松搭建 H5 页面, H5 网站, PC 端网站, LowCode 平台. |
+| [V6.Dooring](https://github.com/MrXujiang/v6.dooring.public) | 可视化大屏解决方案, 提供一套可视化编辑引擎, 助力个人或企业轻松定制自己的可视化大屏应用. |
+| [dooring-electron-lowcode](https://github.com/MrXujiang/dooring-electron-lowcode) | 基于 electron 的 H5-Dooring 编辑器桌面端. |
+| [PC-Dooring](https://github.com/MrXujiang/pc-Dooring) | 网格式拖拽搭建 PC 端页面. |
+| [DooringX](https://github.com/H5-Dooring/dooringx) | 快速高效搭建可视化拖拽平台. |
+
+## 赞助 | Sponsored
+
+开源不易, 有了您的赞助, 我们会做的更好~
+
+
+
+## 技术反馈和交流群 | Technical feedback and communication
+
+微信:beautifulFront
+
+
diff --git a/mock/.gitkeep b/mock/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/package.json b/package.json
index 0cbc8f3..2158bc3 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,7 @@
{
- "scripts": {
- "start": "umi dev",
- "build": "umi build",
- "postinstall": "umi generate tmp",
- "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
- "test": "umi-test",
- "test:coverage": "umi-test --coverage"
- },
- "name": "react-slider-vertify-demo",
+ "name": "@alex_xu/react-slider-vertify",
+ "version": "1.0.5",
+ "author": "alex_xu",
"description": "Slide verification component based on react",
"keywords": [
"component",
@@ -22,6 +16,34 @@
"react-slider-vertify",
"徐小夕"
],
+ "scripts": {
+ "start": "dumi dev",
+ "docs:build": "dumi build",
+ "docs:deploy": "gh-pages -d docs-dist",
+ "build": "father-build",
+ "deploy": "npm run docs:build && npm run docs:deploy",
+ "release": "npm run build && npm publish --access public",
+ "prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"",
+ "test": "umi-test",
+ "test:coverage": "umi-test --coverage"
+ },
+ "contributors": [
+ "alex_xu"
+ ],
+ "files": [
+ "dist",
+ "lib",
+ "es"
+ ],
+ "main": "lib/index.js",
+ "module": "es/index.js",
+ "browserslist": [
+ "last 2 version",
+ "Firefox ESR",
+ "> 1%",
+ "ie >= 9"
+ ],
+ "typings": "dist/index.d.ts",
"gitHooks": {
"pre-commit": "lint-staged"
},
@@ -33,21 +55,32 @@
"prettier --parser=typescript --write"
]
},
+ "homepage": "https://github.com/MrXujiang/react-slider-vertify",
+ "bugs": {
+ "url": "https://github.com/MrXujiang/react-slider-vertify/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com:MrXujiang/react-slider-vertify.git"
+ },
"dependencies": {
- "@alex_xu/react-slider-vertify": "^1.0.4",
- "@ant-design/pro-layout": "^6.5.0",
- "react": "17.x",
- "react-dom": "17.x",
- "umi": "^3.5.17"
+ "@babel/runtime": "^7.15.4",
+ "react": "^16.9.23"
+ },
+ "resolutions": {
+ "@types/react": "^16.9.23"
},
"devDependencies": {
- "@types/react": "^17.0.0",
- "@types/react-dom": "^17.0.0",
- "@umijs/preset-react": "1.x",
- "@umijs/test": "^3.5.17",
+ "@umijs/test": "^3.0.5",
+ "dumi": "^1.0.16",
+ "father-build": "^1.17.2",
+ "gh-pages": "^3.0.0",
"lint-staged": "^10.0.7",
- "prettier": "^2.2.0",
- "typescript": "^4.1.2",
+ "prettier": "^2.2.1",
"yorkie": "^2.0.0"
+ },
+ "license": "MIT",
+ "publishConfig": {
+ "registry": "https://registry.npmjs.com"
}
}
diff --git a/src/Vertify/index.less b/src/Vertify/index.less
new file mode 100644
index 0000000..c59ca34
--- /dev/null
+++ b/src/Vertify/index.less
@@ -0,0 +1,162 @@
+.vertifyWrap {
+ position: relative;
+
+ .block {
+ position: absolute;
+ left: 0;
+ top: 0;
+ cursor: pointer;
+ cursor: grab;
+ }
+
+ .block:active {
+ cursor: grabbing;
+ }
+
+ .sliderContainer {
+ position: relative;
+ text-align: center;
+ width: 310px;
+ height: 40px;
+ line-height: 40px;
+ margin-top: 15px;
+ background: #f7f9fa;
+ color: #45494c;
+ border: 1px solid #e4e7eb;
+ }
+
+ .sliderContainer_active .slider {
+ height: 38px;
+ top: -1px;
+ border: 1px solid #486cd6;
+ }
+
+ .sliderContainer_active .sliderMask {
+ height: 38px;
+ border-width: 1px;
+ }
+
+ .sliderContainer_success .slider {
+ height: 38px;
+ top: -1px;
+ border: 1px solid #0db87f;
+ background-color: #0ca14a !important;
+ }
+
+ .sliderContainer_success .sliderMask {
+ height: 38px;
+ border: 1px solid #0db87f;
+ background-color: #d2f4ef;
+ }
+
+ .sliderContainer_success .sliderIcon {
+ background-position: 0 -26px !important;
+ }
+
+ .sliderContainer_fail .slider {
+ height: 38px;
+ top: -1px;
+ border: 1px solid #f57a7a;
+ background-color: #f57a7a !important;
+ }
+
+ .sliderContainer_fail .sliderMask {
+ height: 38px;
+ border: 1px solid #f57a7a;
+ background-color: #fce1e1;
+ }
+
+ .sliderContainer_fail .sliderIcon {
+ top: 14px;
+ background-position: 0 -82px !important;
+ }
+
+ .sliderContainer_active .sliderText,
+ .sliderContainer_success .sliderText,
+ .sliderContainer_fail .sliderText {
+ display: none;
+ }
+
+ .sliderMask {
+ position: absolute;
+ left: 0;
+ top: 0;
+ height: 40px;
+ border: 0 solid #486cd6;
+ background: #d1e9fe;
+ }
+
+ .slider {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 40px;
+ height: 40px;
+ background: #fff;
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
+ transition: background 0.2s linear;
+ cursor: pointer;
+ cursor: grab;
+ }
+
+ .slider:active {
+ cursor: grabbing;
+ }
+
+ .slider:hover {
+ background: #486cd6;
+ }
+
+ .sliderIcon {
+ font-size: 18px;
+ color: #000;
+ }
+
+ .slider:hover .sliderIcon {
+ color: #fff;
+ }
+
+ .refreshIcon {
+ position: absolute;
+ right: 5px;
+ top: 5px;
+ width: 30px;
+ height: 30px;
+ cursor: pointer;
+ background-size: 32px;
+ }
+
+ .loadingContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 310px;
+ height: 155px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ font-size: 14px;
+ color: #45494c;
+ z-index: 2;
+ background: #edf0f2;
+ }
+
+ .loadingIcon {
+ width: 32px;
+ height: 32px;
+ margin-bottom: 10px;
+ background: url(http://cdn.dooring.cn/dr/icon12.png);
+ background-size: 32px;
+ animation: loading-icon-rotate 0.8s linear infinite;
+ }
+
+ @keyframes loading-icon-rotate {
+ from {
+ transform: rotate(0);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+ }
+}
diff --git a/src/Vertify/index.md b/src/Vertify/index.md
new file mode 100644
index 0000000..9bdf224
--- /dev/null
+++ b/src/Vertify/index.md
@@ -0,0 +1,99 @@
+### 基本使用:
+
+```tsx
+import React from 'react';
+import { Vertify } from '@alex_xu/react-slider-vertify';
+
+export default () => {
+ return ;
+};
+```
+
+### 设置宽高:
+
+```tsx
+import React from 'react';
+import { Vertify } from '@alex_xu/react-slider-vertify';
+
+export default () => {
+ return ;
+};
+```
+
+### 设置滑块边长和半径:
+
+```tsx
+import React from 'react';
+import { Vertify } from '@alex_xu/react-slider-vertify';
+
+export default () => {
+ return ;
+};
+```
+
+### 设置成功, 失败, 刷新时的回调:
+
+```tsx
+import React from 'react';
+import { Vertify } from '@alex_xu/react-slider-vertify';
+
+export default () => {
+ return (
+ alert('success')}
+ onFail={() => alert('fail')}
+ onRefresh={() => alert('refresh')}
+ />
+ );
+};
+```
+
+### 动态设置显示/ 隐藏:
+
+```tsx
+import React, { useState } from 'react';
+import { Vertify } from '@alex_xu/react-slider-vertify';
+
+export default () => {
+ const [visible, setVisible] = useState(false);
+ const show = () => {
+ setVisible(true);
+ };
+ const hide = () => {
+ setVisible(false);
+ };
+ const style = {
+ display: 'inline-block',
+ marginRight: '20px',
+ marginBottom: '20px',
+ width: '100px',
+ padding: '5px 20px',
+ color: '#fff',
+ textAlign: 'center',
+ cursor: 'pointer',
+ background: '#1991FA',
+ };
+ return (
+ <>
+
+ 显示
+
+
+ 隐藏
+
+ alert('success')}
+ onFail={() => alert('fail')}
+ onRefresh={() => alert('refresh')}
+ />
+ >
+ );
+};
+```
+
+
diff --git a/src/Vertify/index.tsx b/src/Vertify/index.tsx
new file mode 100644
index 0000000..b3ed04b
--- /dev/null
+++ b/src/Vertify/index.tsx
@@ -0,0 +1,332 @@
+import React, { useRef, useState, useEffect, ReactNode, memo } from 'react';
+import { getRandomNumberByRange, sum, square } from './tool';
+import './index.less';
+
+interface IVertifyProp {
+ /**
+ * @description canvas宽度
+ * @default 320
+ */
+ width: number;
+ /**
+ * @description canvas高度
+ * @default 160
+ */
+ height: number;
+ /**
+ * @description 滑块边长
+ * @default 42
+ */
+ l: number;
+ /**
+ * @description 滑块半径
+ * @default 9
+ */
+ r: number;
+ /**
+ * @description 是否可见
+ * @default true
+ */
+ visible: boolean;
+ /**
+ * @description 滑块文本
+ * @default 向右滑动填充拼图
+ */
+ text: string | ReactNode;
+ /**
+ * @description 刷新按钮icon, 为icon的url地址
+ * @default -
+ */
+ refreshIcon: string;
+ /**
+ * @description 用于获取随机图片的url地址
+ * @default https://picsum.photos/${id}/${width}/${height}, 具体参考https://picsum.photos/, 只需要实现类似接口即可
+ */
+ imgUrl: string;
+ /**
+ * @description 验证成功回调
+ * @default ():void => {}
+ */
+ onSuccess: VoidFunction;
+ /**
+ * @description 验证失败回调
+ * @default ():void => {}
+ */
+ onFail: VoidFunction;
+ /**
+ * @description 刷新时回调
+ * @default ():void => {}
+ */
+ onRefresh: VoidFunction;
+}
+
+export default memo(
+ ({
+ width = 320,
+ height = 160,
+ l = 42,
+ r = 9,
+ imgUrl,
+ text,
+ refreshIcon = 'http://cdn.dooring.cn/dr/icon12.png',
+ visible = true,
+ onSuccess,
+ onFail,
+ onRefresh,
+ }: IVertifyProp) => {
+ const [isLoading, setLoading] = useState(false);
+ const [sliderLeft, setSliderLeft] = useState(0);
+ const [sliderClass, setSliderClass] = useState('sliderContainer');
+ const [textTip, setTextTip] = useState(text);
+ const canvasRef = useRef(null);
+ const blockRef = useRef(null);
+ const imgRef = useRef(null);
+ const isMouseDownRef = useRef(false);
+ const trailRef = useRef([]);
+ const originXRef = useRef(0);
+ const originYRef = useRef(0);
+ const xRef = useRef(0);
+ const yRef = useRef(0);
+ const PI = Math.PI;
+ const L = l + r * 2 + 3; // 滑块实际边长
+
+ const drawPath = (
+ ctx: any,
+ x: number,
+ y: number,
+ operation: 'fill' | 'clip',
+ ) => {
+ ctx.beginPath();
+ ctx.moveTo(x, y);
+ ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI);
+ ctx.lineTo(x + l, y);
+ ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI);
+ ctx.lineTo(x + l, y + l);
+ ctx.lineTo(x, y + l);
+ ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true);
+ ctx.lineTo(x, y);
+ ctx.lineWidth = 2;
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';
+ ctx.stroke();
+ ctx.globalCompositeOperation = 'destination-over';
+ operation === 'fill' ? ctx.fill() : ctx.clip();
+ };
+
+ const getRandomImgSrc = () => {
+ return (
+ imgUrl ||
+ `https://picsum.photos/id/${getRandomNumberByRange(
+ 0,
+ 1084,
+ )}/${width}/${height}`
+ );
+ };
+
+ const createImg = (onload: VoidFunction) => {
+ const img = new Image();
+ img.crossOrigin = 'Anonymous';
+ img.onload = onload;
+ img.onerror = () => {
+ (img as any).setSrc(getRandomImgSrc()); // 图片加载失败的时候重新加载其他图片
+ };
+
+ (img as any).setSrc = (src: string) => {
+ const isIE = window.navigator.userAgent.indexOf('Trident') > -1;
+ if (isIE) {
+ // IE浏览器无法通过img.crossOrigin跨域,使用ajax获取图片blob然后转为dataURL显示
+ const xhr = new XMLHttpRequest();
+ xhr.onloadend = function (e: any) {
+ const file = new FileReader(); // FileReader仅支持IE10+
+ file.readAsDataURL(e.target.response);
+ file.onloadend = function (e) {
+ img.src = e?.target?.result as string;
+ };
+ };
+ xhr.open('GET', src);
+ xhr.responseType = 'blob';
+ xhr.send();
+ } else img.src = src;
+ };
+
+ (img as any).setSrc(getRandomImgSrc());
+ return img;
+ };
+
+ const draw = (img: HTMLImageElement) => {
+ const canvasCtx = canvasRef.current.getContext('2d');
+ const blockCtx = blockRef.current.getContext('2d');
+ // 随机位置创建拼图形状
+ xRef.current = getRandomNumberByRange(L + 10, width - (L + 10));
+ yRef.current = getRandomNumberByRange(10 + r * 2, height - (L + 10));
+ drawPath(canvasCtx, xRef.current, yRef.current, 'fill');
+ drawPath(blockCtx, xRef.current, yRef.current, 'clip');
+
+ // 画入图片
+ canvasCtx.drawImage(img, 0, 0, width, height);
+ blockCtx.drawImage(img, 0, 0, width, height);
+
+ // 提取滑块并放到最左边
+ const y1 = yRef.current - r * 2 - 1;
+ const ImageData = blockCtx.getImageData(xRef.current - 3, y1, L, L);
+ blockRef.current.width = L;
+ blockCtx.putImageData(ImageData, 0, y1);
+ };
+
+ const initImg = () => {
+ const img = createImg(() => {
+ setLoading(false);
+ draw(img);
+ });
+ imgRef.current = img;
+ };
+
+ const reset = () => {
+ const canvasCtx = canvasRef.current.getContext('2d');
+ const blockCtx = blockRef.current.getContext('2d');
+ // 重置样式
+ setSliderLeft(0);
+ setSliderClass('sliderContainer');
+ blockRef.current.width = width;
+ blockRef.current.style.left = 0 + 'px';
+
+ // 清空画布
+ canvasCtx.clearRect(0, 0, width, height);
+ blockCtx.clearRect(0, 0, width, height);
+
+ // 重新加载图片
+ setLoading(true);
+ imgRef.current.setSrc(getRandomImgSrc());
+ };
+
+ const handleRefresh = () => {
+ reset();
+ typeof onRefresh === 'function' && onRefresh();
+ };
+
+ const verify = () => {
+ const arr = trailRef.current; // 拖动时y轴的移动距离
+ const average = arr.reduce(sum) / arr.length;
+ const deviations = arr.map((x) => x - average);
+ const stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length);
+ const left = parseInt(blockRef.current.style.left);
+ return {
+ spliced: Math.abs(left - xRef.current) < 10,
+ verified: stddev !== 0, // 简单验证拖动轨迹,为零时表示Y轴上下没有波动,可能非人为操作
+ };
+ };
+
+ const handleDragStart = function (e: any) {
+ originXRef.current = e.clientX || e.touches[0].clientX;
+ originYRef.current = e.clientY || e.touches[0].clientY;
+ isMouseDownRef.current = true;
+ };
+
+ const handleDragMove = (e: any) => {
+ if (!isMouseDownRef.current) return false;
+ e.preventDefault();
+ const eventX = e.clientX || e.touches[0].clientX;
+ const eventY = e.clientY || e.touches[0].clientY;
+ const moveX = eventX - originXRef.current;
+ const moveY = eventY - originYRef.current;
+ if (moveX < 0 || moveX + 38 >= width) return false;
+ setSliderLeft(moveX);
+ const blockLeft = ((width - 40 - 20) / (width - 40)) * moveX;
+ blockRef.current.style.left = blockLeft + 'px';
+
+ setSliderClass('sliderContainer sliderContainer_active');
+ trailRef.current.push(moveY);
+ };
+
+ const handleDragEnd = (e: any) => {
+ if (!isMouseDownRef.current) return false;
+ isMouseDownRef.current = false;
+ const eventX = e.clientX || e.changedTouches[0].clientX;
+ if (eventX === originXRef.current) return false;
+ setSliderClass('sliderContainer');
+ const { spliced, verified } = verify();
+ if (spliced) {
+ if (verified) {
+ setSliderClass('sliderContainer sliderContainer_success');
+ typeof onSuccess === 'function' && onSuccess();
+ } else {
+ setSliderClass('sliderContainer sliderContainer_fail');
+ setTextTip('请再试一次');
+ reset();
+ }
+ } else {
+ setSliderClass('sliderContainer sliderContainer_fail');
+ typeof onFail === 'function' && onFail();
+ setTimeout(reset.bind(this), 1000);
+ }
+ };
+
+ useEffect(() => {
+ if (visible) {
+ imgRef.current ? reset() : initImg();
+ }
+ }, [visible]);
+
+ return (
+
+ );
+ },
+);
diff --git a/src/Vertify/tool.ts b/src/Vertify/tool.ts
new file mode 100644
index 0000000..dd2ff84
--- /dev/null
+++ b/src/Vertify/tool.ts
@@ -0,0 +1,13 @@
+function getRandomNumberByRange(start: number, end: number) {
+ return Math.round(Math.random() * (end - start) + start);
+}
+
+function sum(x: number, y: number) {
+ return x + y;
+}
+
+function square(x: number) {
+ return x * x;
+}
+
+export { getRandomNumberByRange, sum, square };
diff --git a/src/index.d.ts b/src/index.d.ts
new file mode 100644
index 0000000..b837218
--- /dev/null
+++ b/src/index.d.ts
@@ -0,0 +1,63 @@
+import React, { ReactNode } from 'react';
+
+interface IVertifyProp {
+ /**
+ * @description canvas宽度
+ * @default 320
+ */
+ width: number;
+ /**
+ * @description canvas高度
+ * @default 160
+ */
+ height: number;
+ /**
+ * @description 滑块边长
+ * @default 42
+ */
+ l: number;
+ /**
+ * @description 滑块半径
+ * @default 9
+ */
+ r: number;
+ /**
+ * @description 是否可见
+ * @default true
+ */
+ visible: boolean;
+ /**
+ * @description 滑块文本
+ * @default 向右滑动填充拼图
+ */
+ text: string | ReactNode;
+ /**
+ * @description 刷新按钮icon, 为icon的url地址
+ * @default -
+ */
+ refreshIcon: string;
+ /**
+ * @description 用于获取随机图片的url地址
+ * @default https://picsum.photos/${id}/${width}/${height}, 具体参考https://picsum.photos/, 只需要实现类似接口即可
+ */
+ imgUrl: string;
+ /**
+ * @description 验证成功回调
+ * @default ():void => {}
+ */
+ onSuccess: VoidFunction;
+ /**
+ * @description 验证失败回调
+ * @default ():void => {}
+ */
+ onFail: VoidFunction;
+ /**
+ * @description 刷新时回调
+ * @default ():void => {}
+ */
+ onRefresh: VoidFunction;
+}
+
+declare const Vertify: React.FC;
+
+export default Vertify;
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..6f9fe88
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1 @@
+export { default as Vertify } from './Vertify';
diff --git a/src/pages/index.jsx b/src/pages/index.jsx
deleted file mode 100644
index d9ac10e..0000000
--- a/src/pages/index.jsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import { useState } from 'react';
-import { Vertify } from '@alex_xu/react-slider-vertify';
-
-export default function IndexPage() {
- const [visible, setVisible] = useState(true);
- const show = () => {
- setVisible(true);
- };
- const hide = () => {
- setVisible(false);
- };
- const style = {
- display: 'inline-block',
- margin: '20px',
- width: '100px',
- padding: '5px 20px',
- color: '#fff',
- textAlign: 'center',
- cursor: 'pointer',
- background: '#1991FA',
- };
- return (
-
-
alert('success')}
- onFail={() => alert('fail')}
- onRefresh={() => alert('refresh')}
- />
-
- 显示
-
-
- 隐藏
-
-
-
更多精彩
-

-
-
- );
-}
diff --git a/tsconfig.json b/tsconfig.json
index 6d42f8c..de15e0a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,9 +3,8 @@
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
- "resolveJsonModule": true,
"importHelpers": true,
- "jsx": "react-jsx",
+ "jsx": "react",
"esModuleInterop": true,
"sourceMap": true,
"baseUrl": "./",
@@ -16,13 +15,6 @@
},
"allowSyntheticDefaultImports": true
},
- "include": [
- "mock/**/*",
- "src/**/*",
- "config/**/*",
- ".umirc.ts",
- "typings.d.ts"
- ],
"exclude": [
"node_modules",
"lib",
diff --git a/typings.d.ts b/typings.d.ts
index 06c8a5b..71e0e9f 100644
--- a/typings.d.ts
+++ b/typings.d.ts
@@ -1,10 +1,2 @@
declare module '*.css';
declare module '*.less';
-declare module '*.png';
-declare module '*.svg' {
- export function ReactComponent(
- props: React.SVGProps,
- ): React.ReactElement;
- const url: string;
- export default url;
-}