diff --git a/package-lock.json b/package-lock.json
index fe19286..ea2de7a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,8 @@
"license": "ISC",
"dependencies": {
"@types/uuid": "^9.0.1",
+ "@uiw/react-color-alpha": "^1.1.3",
+ "classnames": "^2.3.2",
"framer-motion": "^8.5.5",
"uuid": "^9.0.0"
},
@@ -39,6 +41,7 @@
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"less-loader": "^11.1.0",
+ "moment": "^2.29.4",
"postcss": "^8.4.21",
"react": "^18.2.0",
"rollup": "^3.19.1",
@@ -1787,7 +1790,6 @@
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
"integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
- "dev": true,
"dependencies": {
"regenerator-runtime": "^0.13.11"
},
@@ -3493,6 +3495,38 @@
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
"dev": true
},
+ "node_modules/@uiw/color-convert": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-1.1.3.tgz",
+ "integrity": "sha512-/ZtvW4YWfM9vzrbZOmlSY3DQ0mll8D6uY87yITJnDmOh50qOpiZPC2/l3ReoUxbyS6xLcn4/ba1DzH5BEx6dCg==",
+ "peerDependencies": {
+ "@babel/runtime": ">=7.19.0"
+ }
+ },
+ "node_modules/@uiw/react-color-alpha": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@uiw/react-color-alpha/-/react-color-alpha-1.1.3.tgz",
+ "integrity": "sha512-JenSKVRuDbScq0FUeIVVkIuP3x3SMdyqlwh6ik00wyvHQiaq7W1srihGtlRKlJKrignzELNprIppulI2euwvCA==",
+ "dependencies": {
+ "@uiw/color-convert": "1.1.3",
+ "@uiw/react-drag-event-interactive": "1.1.3"
+ },
+ "peerDependencies": {
+ "@babel/runtime": ">=7.19.0",
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@uiw/react-drag-event-interactive": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@uiw/react-drag-event-interactive/-/react-drag-event-interactive-1.1.3.tgz",
+ "integrity": "sha512-PHbXPQELjh3TaU8m/wFblbQyiKujb/hHfs94PKfB69YnS7uZPKCMsasbxm08AmMVYSZ92MG1Ip/vIKVoAxEEaQ==",
+ "peerDependencies": {
+ "@babel/runtime": ">=7.19.0",
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
"node_modules/@vue/compiler-core": {
"version": "3.2.47",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz",
@@ -4883,6 +4917,11 @@
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
"dev": true
},
+ "node_modules/classnames": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
+ "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
+ },
"node_modules/clean-css": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz",
@@ -10290,6 +10329,15 @@
"node": ">=10"
}
},
+ "node_modules/moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -11765,8 +11813,7 @@
"node_modules/regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
- "dev": true
+ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"node_modules/regenerator-transform": {
"version": "0.15.1",
@@ -15489,7 +15536,6 @@
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
"integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
- "dev": true,
"requires": {
"regenerator-runtime": "^0.13.11"
}
@@ -16857,6 +16903,27 @@
"integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
"dev": true
},
+ "@uiw/color-convert": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-1.1.3.tgz",
+ "integrity": "sha512-/ZtvW4YWfM9vzrbZOmlSY3DQ0mll8D6uY87yITJnDmOh50qOpiZPC2/l3ReoUxbyS6xLcn4/ba1DzH5BEx6dCg==",
+ "requires": {}
+ },
+ "@uiw/react-color-alpha": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@uiw/react-color-alpha/-/react-color-alpha-1.1.3.tgz",
+ "integrity": "sha512-JenSKVRuDbScq0FUeIVVkIuP3x3SMdyqlwh6ik00wyvHQiaq7W1srihGtlRKlJKrignzELNprIppulI2euwvCA==",
+ "requires": {
+ "@uiw/color-convert": "1.1.3",
+ "@uiw/react-drag-event-interactive": "1.1.3"
+ }
+ },
+ "@uiw/react-drag-event-interactive": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@uiw/react-drag-event-interactive/-/react-drag-event-interactive-1.1.3.tgz",
+ "integrity": "sha512-PHbXPQELjh3TaU8m/wFblbQyiKujb/hHfs94PKfB69YnS7uZPKCMsasbxm08AmMVYSZ92MG1Ip/vIKVoAxEEaQ==",
+ "requires": {}
+ },
"@vue/compiler-core": {
"version": "3.2.47",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz",
@@ -17996,6 +18063,11 @@
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
"dev": true
},
+ "classnames": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
+ "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
+ },
"clean-css": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz",
@@ -22060,6 +22132,12 @@
"brace-expansion": "^2.0.1"
}
},
+ "moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "dev": true
+ },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -23084,8 +23162,7 @@
"regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
- "dev": true
+ "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"regenerator-transform": {
"version": "0.15.1",
diff --git a/package.json b/package.json
index 6f4b3ba..b216125 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,7 @@
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"less-loader": "^11.1.0",
+ "moment": "^2.29.4",
"postcss": "^8.4.21",
"react": "^18.2.0",
"rollup": "^3.19.1",
@@ -76,7 +77,9 @@
},
"dependencies": {
"@types/uuid": "^9.0.1",
+ "@uiw/react-color-alpha": "^1.1.3",
+ "classnames": "^2.3.2",
"framer-motion": "^8.5.5",
"uuid": "^9.0.0"
}
-}
\ No newline at end of file
+}
diff --git a/rollup.config.mjs b/rollup.config.mjs
index b8ca7dc..66ef197 100644
--- a/rollup.config.mjs
+++ b/rollup.config.mjs
@@ -68,6 +68,6 @@ export default [
input: "dist/esm/types/index.d.ts",
output: [{ file: "dist/index.d.ts", format: "esm" }],
plugins: [dts.default()],
- external: [/\.less$/], // telling rollup anything that is .css aren't part of type exports
+ external: [/\.less$/], // telling rollup anything that is .css aren't part of type exports
},
-]
\ No newline at end of file
+]
diff --git a/src/_test.css b/src/_test.css
new file mode 100644
index 0000000..7da3761
--- /dev/null
+++ b/src/_test.css
@@ -0,0 +1,9 @@
+:root {
+ --background: #ebedff;
+ --blueDark: #5c6dff;
+ --fadedGary: #818181;
+ --white: #ffffff;
+ --black: #000000;
+ --white-shadow: 0px 0px 13px 5px rgba(173, 182, 255, 0.25);
+}
+
diff --git a/src/_test.less b/src/_test.less
new file mode 100644
index 0000000..718ed92
--- /dev/null
+++ b/src/_test.less
@@ -0,0 +1,5 @@
+@import '../src/common/style/index.less';
+
+a{
+ text-decoration: none;
+}
diff --git a/src/_test.tsx b/src/_test.tsx
index b22835b..16141ba 100644
--- a/src/_test.tsx
+++ b/src/_test.tsx
@@ -1,17 +1,45 @@
+import React, { useEffect, useRef, useState } from "react";
+import ReactDom from "react-dom";
+import Modal from "./components/modal/modal";
+import Upload from "./components/upload/upload";
+import Tab from "./components/tab/tab";
+import * as GOJI from "goji_ui";
+import DropDown from "./components/dropDown";
+import Button from "./components/button/button";
+import "./_test.less";
+import Alpha from "@uiw/react-color-alpha";
+import Input from "./components/input/input";
+import useCountdown from "./components/countdown";
-import React, { useState } from 'react';
-import ReactDom from 'react-dom'
-import Modal from './components/modal/modal';
-import Upload from './components/upload/upload';
-import Tab from './components/tab/tab';
+function App() {
+ const [visible, setVisible] = useState(false);
+ const [ev, setEv] = useState(false);
+ const [modalVisible, setModalVisible] = useState(false);
+ const [hsva, setHsva] = useState({ h: 0, s: 0, v: 20, a: 1 });
+ const [value, setValue] = useState(10);
+ const { date } = useCountdown(3);
-import * as GOJI from 'goji_ui'
+ const handleClick = (e: unknown) => {
+ setValue(e?.target.value);
+ console.log("e", e?.target.value);
+ };
-function App() {
- const [visible, setVisible] = useState(false)
- const [ev, setEv] = useState(false)
- return
}
items={[
@@ -27,77 +55,210 @@ function App() {
}
]}
/> */}
+ test
+
+ {
+ setEv(true);
+ }}
+ hiddenStyle={{
+ height: "0px",
+ overflow: "hidden",
+ }}
+ tabContentVisible={ev}
+ extSelector={'[aria-label="tab"]'}
+ extension={
+ {
+ setEv(!ev);
+ }}
+ className="ext"
+ >
+ 这是扩展的内容
+
+ }
+ items={[
+ {
+ title: "tab1",
+ key: "tab1",
+ children: tab1
,
+ },
+ {
+ title: "tab2",
+ key: "tab2",
+ children: tab2
,
+ },
+ ]}
+ />
+ {
+ setVisible(false);
+ }}
+ visible={visible}
+ >
+
+ how to set default value for typescript interface field
+
+
+
+ {
+ for (var i = 0; i < f.length; i++) {
+ console.log(f[i].name);
+ }
+ return new Promise((r, j) => {
+ setTimeout(() => {
+ r(f);
+ }, 1000);
+ });
+ }}
+ valueFilter={({ response }) => {
+ return (response as Record).url;
+ }}
+ onComplete={(res: any[]) => {
+ console.log(res);
+ }}
+ >
+ 请选择文件
+
+ {/* {
+ setModalVisible(!modalVisible);
+ }}
+ position="topRight"
+ width={150}
+ modelContent={[
+ {
+ id: "1",
+ label: "first Item",
+ },
+ {
+ id: "2",
+ label: "second Item",
+ },
+ ]}
+ // className={"modless"}
+ >
+ SHOW MODEL
+ */}
+ {
+ setModalVisible(!modalVisible);
+ }}
+ position="bottom"
+ width={150}
+ modelContent={"KDSK"}
+ icons={[
+ ,
+ ,
+ ]}
+ // className={"modless"}
+ >
+ SHOW MODEL
+
+
+
+
+
+
+
+
+
+
- test
-
- {
- setEv(true)
- }}
- hiddenStyle={{
- height: '0px',
- overflow: 'hidden'
- }}
- tabContentVisible={ev}
- extSelector={'[aria-label="tab"]'}
- extension={ { setEv(!ev) }} className="ext">这是扩展的内容
}
- items={[
- {
- title: "tab1",
- key: "tab1",
- children: tab1
- },
- {
- title: "tab2",
- key: "tab2",
- children: tab2
- }
- ]}
- />
-
- {
- setVisible(false)
- }}
- visible={visible}
- >
-
- how to set default value for typescript interface field
-
-
-
+
+
- {
- for (var i = 0; i < f.length; i++) {
- console.log(f[i].name)
- }
- return new Promise((r, j) => {
- setTimeout(() => {
- r(f)
- }, 1000);
- })
- }}
+
- valueFilter={({ response }) => {
- return (response as Record).url
- }}
- onComplete={(res: any[]) => {
- console.log(res)
- }}
- >
- 请选择文件
-
-
+ <>
+ {
+ setHsva({ ...hsva, ...newAlpha });
+ }}
+ background={`linear-gradient(to right,rgb(218,44,2) 0%, rgb(253,253,32)20%, rgb(255,255,255) 35%, rgb(255,255,255) 60% ,#D0F5FB 65%, rgb(98,165,218) 100%)`}
+ />
+ {/*
+ {JSON.stringify(hsva)}
+
*/}
+ >
+
+ );
}
-ReactDom.render(, document.getElementById("app"))
\ No newline at end of file
+ReactDom.render(, document.getElementById("app"));
diff --git a/src/common/style/index.css b/src/common/style/index.css
new file mode 100644
index 0000000..98383e1
--- /dev/null
+++ b/src/common/style/index.css
@@ -0,0 +1,8 @@
+:root {
+ --background: #ebedff;
+ --blueDark: #5c6dff;
+ --fadedGary: #818181;
+ --white: #ffffff;
+ --black: #000000;
+ --white-shadow: 0px 0px 13px 5px rgba(173, 182, 255, 0.25);
+}
diff --git a/src/common/style/index.less b/src/common/style/index.less
new file mode 100644
index 0000000..97b05a3
--- /dev/null
+++ b/src/common/style/index.less
@@ -0,0 +1,9 @@
+// :root 伪类选择器 匹配文档树的根节点
+:root {
+ --background: #ebedff;
+ --blueDark: #5c6dff;
+ --fadedGary: #818181;
+ --white: #ffffff;
+ --black: #000000;
+ --white-shadow: 0px 0px 13px 5px rgba(173, 182, 255, 0.25);
+}
diff --git a/src/components/button/button.tsx b/src/components/button/button.tsx
new file mode 100644
index 0000000..9855c5f
--- /dev/null
+++ b/src/components/button/button.tsx
@@ -0,0 +1,71 @@
+import React from "react";
+import "./index.less";
+import classnames from "classnames";
+
+//如何继承 DOMAttributes
+
+type type = "primary" | "link" | "dashed" | "text" | "disable";
+type shape = "round" | "circle";
+type iconPos = "left" | "right";
+
+interface IButton extends React.ButtonHTMLAttributes {
+ types?: type | undefined;
+ style?: React.CSSProperties | undefined;
+ className?: string | undefined;
+ children?: React.ReactNode | undefined;
+ shape?: shape | undefined;
+ icon?: React.ReactNode | undefined;
+ iconPos?: iconPos | undefined;
+ herf?: string | undefined;
+ disabled?: boolean | undefined;
+}
+
+const Button = (props: IButton) => {
+ const { types, style, className, children, shape, icon, iconPos, disabled } =
+ props;
+
+ const getBtnClass = () => {
+ switch (types) {
+ case "primary":
+ return "primaryButton gojiButton";
+ case "dashed":
+ return "dashedButton gojiButton";
+ case "link":
+ return "linkButton gojiButton";
+ case "text":
+ return "textButton gojiButton";
+ case "disable":
+ return "disable gojiButton";
+ default:
+ return "gojiButton";
+ }
+ };
+
+ const shapes = () => {
+ switch (shape) {
+ case "circle":
+ return "circle";
+ case "round":
+ return "round";
+ default:
+ break;
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default Button;
diff --git a/src/components/button/index.css b/src/components/button/index.css
new file mode 100644
index 0000000..2779de2
--- /dev/null
+++ b/src/components/button/index.css
@@ -0,0 +1,61 @@
+.gojiButton {
+ display: inline-block;
+ font-size: 14px;
+ padding: 0px 15px;
+ border-radius: 6px;
+ cursor: pointer;
+ background-color: #fff;
+ color: #000;
+ text-align: center;
+ border: 1px solid;
+ margin: 6px;
+ line-height: 30px;
+}
+.gojiButton:hover {
+ color: red;
+}
+.primaryButton {
+ font-size: 14px;
+ padding: 0px 15px;
+ border-radius: 6px;
+ cursor: pointer;
+ background-color: #fff;
+ list-style: none;
+ color: rgba(0, 0, 0, 0.88);
+ text-align: center;
+ border: 1px solid;
+}
+.primaryButton:hover {
+ background-color: green !important;
+ color: #fff !important;
+}
+.linkButton {
+ border: none;
+ color: green;
+}
+.linkButton:hover {
+ color: #1f77db !important;
+}
+.textButton {
+ border: none;
+}
+.textButton:hover {
+ background-color: #b3b4b4;
+ color: #000;
+}
+.round {
+ border-radius: 40px;
+}
+.circle {
+ border-radius: 50%;
+}
+.dashedButton {
+ border: 1px dashed;
+}
+.disableButton {
+ cursor: not-allowed !important;
+ border-color: #d9d9d9;
+ color: rgba(0, 0, 0, 0.25);
+ background-color: rgba(0, 0, 0, 0.04);
+ box-shadow: none;
+}
diff --git a/src/components/button/index.less b/src/components/button/index.less
new file mode 100644
index 0000000..5cd6cdc
--- /dev/null
+++ b/src/components/button/index.less
@@ -0,0 +1,72 @@
+.gojiButton {
+ display: inline-block;
+ font-size: 14px;
+ padding: 0px 15px;
+ border-radius: 6px;
+ cursor: pointer;
+ background-color: #fff;
+ color: #000;
+ text-align: center;
+ border: 1px solid;
+ margin: 6px;
+ line-height: 30px;
+}
+
+.gojiButton:hover {
+ color: red;
+}
+
+.primaryButton {
+ font-size: 14px;
+ padding: 0px 15px;
+ border-radius: 6px;
+ cursor: pointer;
+ background-color: #fff;
+ list-style: none;
+ color: rgba(0, 0, 0, 0.88);
+ text-align: center;
+ border: 1px solid;
+}
+
+.primaryButton:hover {
+ background-color: green !important;
+ color: #fff !important;
+}
+
+.linkButton {
+ border: none;
+ color: green;
+}
+
+.linkButton:hover {
+ color: rgb(31, 119, 219) !important;
+}
+
+.textButton {
+ border: none;
+}
+
+.textButton:hover {
+ background-color: rgb(179, 180, 180);
+ color: #000;
+}
+
+.round {
+ border-radius: 40px;
+}
+
+.circle {
+ border-radius: 50%;
+}
+
+.dashedButton {
+ border: 1px dashed;
+}
+
+.disableButton {
+ cursor: not-allowed !important;
+ border-color: #d9d9d9;
+ color: rgba(0, 0, 0, 0.25);
+ background-color: rgba(0, 0, 0, 0.04);
+ box-shadow: none;
+}
diff --git a/src/components/countdown/index.tsx b/src/components/countdown/index.tsx
new file mode 100644
index 0000000..f2025ac
--- /dev/null
+++ b/src/components/countdown/index.tsx
@@ -0,0 +1,27 @@
+import { useEffect, useRef, useState } from "react";
+
+export default function useCountdown(time: number) {
+ const [date, setDate] = useState(time);
+ const timeRef = useRef();
+
+ useEffect(() => {
+ //timeRef.current是定时器
+ timeRef.current = setInterval(() => {
+ setDate((t) => t - 1);
+ }, 1000);
+
+ return () => {
+ clearInterval(timeRef.current);
+ };
+ }, []);
+
+ useEffect(() => {
+ if (date <= 0) {
+ clearInterval(timeRef.current);
+ }
+ }, [date]);
+
+ return {
+ date,
+ };
+}
diff --git a/src/components/dropDown/dropDown.css b/src/components/dropDown/dropDown.css
new file mode 100644
index 0000000..ae20d94
--- /dev/null
+++ b/src/components/dropDown/dropDown.css
@@ -0,0 +1,156 @@
+.dropDown {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ box-shadow: var(--white-shadow);
+ padding: 12px 24px;
+ cursor: pointer;
+ position: relative;
+ border-radius: 5px;
+}
+.dropDown .dropDownOption {
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+ padding: 2px;
+}
+.dropDown .dropDownOption .dropDownOptionItem {
+ padding: 12px;
+ color: var(--black);
+}
+.dropDown .dropDownOption .dropDownOptionItem:hover {
+ background: var(--background);
+ color: var(--fadedGary);
+}
+.dropDown .PositionTop {
+ position: absolute;
+ top: -12px;
+ left: 0;
+ transform: translateY(-100%);
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+}
+.dropDown .PositionTop::after {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: #ffffff transparent transparent transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: 91px;
+ right: 45%;
+ z-index: 99;
+}
+.dropDown .PositionTop::before {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: #ffffff transparent transparent transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: 91px;
+ right: 45%;
+ z-index: 99;
+}
+.dropDown .PositionTopRight {
+ position: absolute;
+ top: -12px;
+ left: 0;
+ transform: translateY(-100%);
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+}
+.dropDown .PositionTopRight::after {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: #ffffff transparent transparent transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: 91px;
+ right: 9px;
+ z-index: 99;
+}
+.dropDown .PositionTopRight::before {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: #ffffff transparent transparent transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: 91px;
+ right: 9px;
+ z-index: 99;
+}
+.dropDown .PositionBottom {
+ position: absolute;
+ left: 0;
+ bottom: -10px;
+ transform: translateY(100%);
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+}
+.dropDown .PositionBottom::after {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: transparent transparent #ffffff transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: -14px;
+ right: 45%;
+ z-index: 99;
+}
+.dropDown .PositionBottom::before {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: transparent transparent #ffffff transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: -14px;
+ right: 45%;
+ z-index: 99;
+}
+.dropDown .PositionBottomRight {
+ position: absolute;
+ left: 0;
+ bottom: -10px;
+ transform: translateY(100%);
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+}
+.dropDown .PositionBottomRight::after {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 6px;
+ border-color: transparent transparent #a07676 transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: -11px;
+ right: 9px;
+ z-index: 99;
+}
+.dropDown .PositionBottomRight::before {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 6px;
+ border-color: transparent transparent #884b4b transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: -11px;
+ right: 9px;
+ z-index: 99;
+}
diff --git a/src/components/dropDown/dropDown.less b/src/components/dropDown/dropDown.less
new file mode 100644
index 0000000..d2fc826
--- /dev/null
+++ b/src/components/dropDown/dropDown.less
@@ -0,0 +1,170 @@
+.dropDown {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ box-shadow: var(--white-shadow);
+ padding: 12px 24px;
+ cursor: pointer;
+ position: relative;
+ border-radius: 5px;
+
+ .dropDownOption {
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+ padding: 2px;
+ .dropDownOptionItem {
+ padding: 12px;
+ color: var(--black);
+ }
+
+ .dropDownOptionItem:hover {
+ background: var(--background);
+ color: var(--fadedGary);
+ }
+ }
+
+ .PositionTop {
+ position: absolute;
+ top: -12px;
+ left: 0;
+ transform: translateY(-100%);
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+ }
+
+ .PositionTop::after {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: #ffffff transparent transparent transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: 91px;
+ right: 45%;
+ z-index: 99;
+ }
+
+ .PositionTop::before {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: #ffffff transparent transparent transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: 91px;
+ right: 45%;
+ z-index: 99;
+ }
+
+ .PositionTopRight {
+ position: absolute;
+ top: -12px;
+ left: 0;
+ transform: translateY(-100%);
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+ }
+
+ .PositionTopRight::after {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: #ffffff transparent transparent transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: 91px;
+ right: 9px;
+ z-index: 99;
+ }
+
+ .PositionTopRight::before {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: #ffffff transparent transparent transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: 91px;
+ right: 9px;
+ z-index: 99;
+ }
+
+ .PositionBottom {
+ position: absolute;
+ left: 0;
+ bottom: -10px;
+ transform: translateY(100%);
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+ }
+
+ .PositionBottom::after {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: transparent transparent #ffffff transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: -14px;
+ right: 45%;
+ z-index: 99;
+ }
+
+ .PositionBottom::before {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 8px;
+ border-color: transparent transparent #ffffff transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: -14px;
+ right: 45%;
+ z-index: 99;
+ }
+
+ .PositionBottomRight {
+ position: absolute;
+ left: 0;
+ bottom: -10px;
+ transform: translateY(100%);
+ background: var(--white);
+ width: 100%;
+ box-shadow: var(--white-shadow);
+ }
+
+ .PositionBottomRight::after {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 6px;
+ border-color: transparent transparent #a07676 transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: -11px;
+ right: 9px;
+ z-index: 99;
+ }
+
+ .PositionBottomRight::before {
+ width: 0;
+ height: 0;
+ content: "";
+ border-width: 6px;
+ border-color: transparent transparent #884b4b transparent;
+ border-style: dashed dashed solid dashed;
+ position: absolute;
+ top: -11px;
+ right: 9px;
+ z-index: 99;
+ }
+}
diff --git a/src/components/dropDown/index.tsx b/src/components/dropDown/index.tsx
new file mode 100644
index 0000000..cdd777d
--- /dev/null
+++ b/src/components/dropDown/index.tsx
@@ -0,0 +1,90 @@
+import React, { ReactNode, useState } from "react";
+import { createPortal } from "react-dom";
+import "./dropDown.less";
+import { v4 as uuidv4 } from "uuid";
+type trigger = "click" | "hover";
+type position = "bottomRight" | "bottom" | "top" | "topRight";
+
+type IDropDown = {
+ trigger: trigger;
+ style?: React.CSSProperties;
+ className?: string;
+ children?: ReactNode;
+ visible?: boolean;
+ setVisible?: any;
+ modelContent?: ReactNode;
+ width?: number;
+ position?: position;
+ onChangeVisible: () => void;
+ icons: ReactNode[];
+};
+
+const DropDown: React.FC = ({
+ trigger,
+ style,
+ width,
+ className,
+ children,
+ visible,
+ modelContent,
+ position,
+ icons,
+ setVisible,
+ onChangeVisible,
+}) => {
+ // const dropDown = document.getElementById("dropDown") as HTMLElement;
+
+ const [optionValue, setOptionValue] = useState(children);
+
+ const fixedPosition = (position: position) => {
+ switch (position) {
+ case "bottom":
+ return "PositionBottom";
+ case "bottomRight":
+ return "PositionBottomRight";
+ case "top":
+ return "PositionTop";
+ case "topRight":
+ return "PositionTopRight";
+ default:
+ break;
+ }
+ };
+
+ return (
+ <>
+ {trigger === "click" ? (
+ onChangeVisible()}
+ style={{ width: `${width}px`, ...style }}
+ >
+ {optionValue}
+ {visible ? icons[0] : icons[1]}
+ {visible && (
+
+ {modelContent}
+
+ )}
+
+ ) : (
+ setVisible(true)}
+ onMouseLeave={() => setVisible(false)}
+ >
+ {optionValue}
+ {visible ? icons[0] : icons[1]}
+ {visible && (
+
+ {modelContent}
+
+ )}
+
+ )}
+ >
+ );
+};
+
+export default DropDown;
diff --git a/src/components/dropDown/model.tsx b/src/components/dropDown/model.tsx
new file mode 100644
index 0000000..855e68a
--- /dev/null
+++ b/src/components/dropDown/model.tsx
@@ -0,0 +1,50 @@
+import classNames from "classnames";
+import React from "react";
+import { createPortal } from "react-dom";
+import styles from "./dropDown.module.less";
+
+interface IModel {
+ modelContent: object[] | undefined;
+ dropDown?: HTMLElement | undefined;
+ width?: number | undefined;
+ fixedPosition?: any;
+ position?: string | undefined;
+ className?: string | undefined;
+ style?: React.CSSProperties;
+}
+
+const Model: React.FC = ({
+ modelContent,
+ dropDown,
+ width,
+ fixedPosition,
+ position,
+ className,
+ style,
+}) => {
+ return (
+ <>
+ {createPortal(
+
+
+ {modelContent?.map((item) => {
+ return (
+ -
+ {item?.label}
+
+ );
+ })}
+
+
,
+ dropDown
+ )}
+ >
+ );
+};
+
+export default Model;
diff --git a/src/components/input/index.css b/src/components/input/index.css
new file mode 100644
index 0000000..0accd21
--- /dev/null
+++ b/src/components/input/index.css
@@ -0,0 +1,36 @@
+.inputBox {
+ border: 1px solid #036df7;
+ display: inline;
+ padding: 4px;
+ border-radius: 5px;
+ margin: 10px;
+}
+.inputBox input {
+ outline: none;
+ border: none;
+ height: 19px;
+}
+.inputBox .numberLimit {
+ font-size: 14px;
+}
+.action {
+ border: 1px solid red;
+ display: inline;
+ padding: 4px;
+ border-radius: 5px;
+ margin: 10px;
+}
+.action input {
+ outline: none;
+ border: none;
+ height: 19px;
+}
+.action .numberLimit {
+ font-size: 14px;
+}
+.message {
+ margin: 0;
+ padding: 0;
+ color: red;
+ font-size: 12px;
+}
diff --git a/src/components/input/index.less b/src/components/input/index.less
new file mode 100644
index 0000000..bd420c7
--- /dev/null
+++ b/src/components/input/index.less
@@ -0,0 +1,39 @@
+.inputBox {
+ border: 1px solid rgb(3, 109, 247);
+ display: inline;
+ padding: 4px;
+ border-radius: 5px;
+ margin: 10px;
+ input {
+ outline: none;
+ border: none;
+ height: 19px;
+ }
+
+ .numberLimit {
+ font-size: 14px;
+ }
+}
+
+.action {
+ border: 1px solid red;
+ display: inline;
+ padding: 4px;
+ border-radius: 5px;
+ margin: 10px;
+ input {
+ outline: none;
+ border: none;
+ height: 19px;
+ }
+ .numberLimit {
+ font-size: 14px;
+ }
+}
+
+.message {
+ margin: 0;
+ padding: 0;
+ color: red;
+ font-size: 12px;
+}
diff --git a/src/components/input/input.tsx b/src/components/input/input.tsx
new file mode 100644
index 0000000..57ee9fe
--- /dev/null
+++ b/src/components/input/input.tsx
@@ -0,0 +1,59 @@
+import React, { useEffect, useState } from "react";
+import "./index.less";
+
+interface IProps extends React.HTMLProps {
+ className?: string | undefined;
+ style?: React.CSSProperties;
+ value: string | number | undefined;
+ maxLength?: number | undefined;
+ defaultValue?: string | undefined;
+}
+
+const Input = (props: IProps) => {
+ const { value, defaultValue, maxLength, className, style } = props;
+ const [inputLength, setInputLength] = useState(0);
+
+ useEffect(() => {
+ if (value === "string") {
+ let inputValues = value?.split("").length;
+ setInputLength(inputValues);
+ } else {
+ setInputLength(0);
+ }
+ }, [value]);
+
+ useEffect(() => {
+ if (defaultValue) {
+ if (typeof defaultValue === "number") {
+ let defaultValueArrayLength = defaultValue
+ ?.toString()
+ ?.split("")?.length;
+ setInputLength(defaultValueArrayLength);
+ } else if (typeof defaultValue === "string") {
+ let defaultValues = defaultValue.split("").length;
+ setInputLength(defaultValues);
+ } else {
+ setInputLength(0);
+ }
+ }
+ }, []);
+
+ return (
+ <>
+
+
+ {`${inputLength}/${
+ maxLength && maxLength
+ }`}
+
+ {inputLength > 10 && (
+ 内容超过10,请重新输入
+ )}
+ >
+ );
+};
+
+export default Input;
diff --git "a/static/\344\270\213\347\256\255\345\244\264.jpg" "b/static/\344\270\213\347\256\255\345\244\264.jpg"
new file mode 100644
index 0000000..bb86ebe
Binary files /dev/null and "b/static/\344\270\213\347\256\255\345\244\264.jpg" differ