├── .npmignore ├── demo ├── mock │ └── .gitkeep ├── src │ ├── pages │ │ ├── index.less │ │ └── index.tsx │ └── widgets │ │ ├── 1.jpg │ │ ├── clock │ │ ├── snapshot.png │ │ ├── index.tsx │ │ ├── index.less │ │ └── component.tsx │ │ ├── guide │ │ ├── snapshot.png │ │ ├── index.less │ │ ├── index.tsx │ │ └── component.tsx │ │ ├── ring │ │ ├── snapshot.png │ │ ├── data.ts │ │ ├── index.tsx │ │ ├── index.less │ │ └── component.tsx │ │ ├── todo │ │ ├── snapshot.png │ │ ├── index.tsx │ │ ├── data.ts │ │ ├── index.less │ │ └── component.tsx │ │ ├── column │ │ ├── snapshot.png │ │ ├── data.ts │ │ ├── index.tsx │ │ ├── index.less │ │ └── component.tsx │ │ ├── popular │ │ ├── snapshot.png │ │ ├── index.tsx │ │ ├── index.less │ │ ├── component.tsx │ │ └── data.ts │ │ ├── index.tsx │ │ └── README.md ├── .umi │ ├── core │ │ ├── polyfill.ts │ │ ├── umiExports.ts │ │ ├── pluginRegister.ts │ │ ├── plugin.ts │ │ ├── history.ts │ │ ├── routes.ts │ │ ├── devScripts.ts │ │ └── pluginConfig.d.ts │ ├── .cache │ │ └── babel-loader │ │ │ ├── 09e867201bdb7e28d581abcd4b7d8c14.json.gz │ │ │ ├── 0ac976858665b23e2ee7127c5b87edf3.json.gz │ │ │ ├── 0f9f9ce9baa523bbc23cadbe85d86873.json.gz │ │ │ ├── 11aeb04f5f35e0949f6507c66dbaeb13.json.gz │ │ │ ├── 15309499acb061557869b06ee0393973.json.gz │ │ │ ├── 1e4694fef7193a8ee8c86c6838bc5674.json.gz │ │ │ ├── 26fb2eeb2184b099b392ce7dbfc51cb8.json.gz │ │ │ ├── 2b9e01ec932354f871bb71fcb4936896.json.gz │ │ │ ├── 30308bebb1aebf38ff61bae8220a739d.json.gz │ │ │ ├── 32f8557a920c90011a2533696d149b4f.json.gz │ │ │ ├── 32ffd9e15066e02886196f859829a235.json.gz │ │ │ ├── 42f795da0842c2fd9207ae2f1fe92aac.json.gz │ │ │ ├── 4950088de873e301fdbbe82ba42feaa8.json.gz │ │ │ ├── 4e787fcdccd8283fef47d49a6be85b8d.json.gz │ │ │ ├── 4f06a6bcb050578d1160df3e2ad79ca5.json.gz │ │ │ ├── 51f5b8c3e30c06658dc09f82415eebef.json.gz │ │ │ ├── 57ff7afbe7fe4ce7f53597d795b51e81.json.gz │ │ │ ├── 5e671ad88303752645494a4d4831215d.json.gz │ │ │ ├── 6717cd3e402d830dcaada2f82eca381f.json.gz │ │ │ ├── 69ad0feed2f31abd7d77e81d11a730a2.json.gz │ │ │ ├── 6b912c10e38a557703d36e1523192cbc.json.gz │ │ │ ├── 6d477ca635ba3baf6f64693af11fe5ed.json.gz │ │ │ ├── 79e851082f89733ad62b979814898df3.json.gz │ │ │ ├── 7aea70718860af13a74a7fc40b75cecf.json.gz │ │ │ ├── 856074fab53abc287738a097421113c3.json.gz │ │ │ ├── 8687794b72d1fb1769eb6daadca6ab1a.json.gz │ │ │ ├── 889ce2be5d70438730885348c1b9c801.json.gz │ │ │ ├── 8e5eb62038961cb9a7a6a1beb1e4f4f8.json.gz │ │ │ ├── 95f7dede3dd07cf809f9169637e7b3fe.json.gz │ │ │ ├── 9626603194f361dd867ce902482c242f.json.gz │ │ │ ├── 9989483da0ab50d45c1d3d3177e2f658.json.gz │ │ │ ├── 9eba704fff91d2bf1cd82dcf13eccbd1.json.gz │ │ │ ├── a3b741ceb79e62d12bba554098030622.json.gz │ │ │ ├── b0c25a98daede2344c53d49aad31eb60.json.gz │ │ │ ├── b1070acee18f868eb3a0e7c7c56e760d.json.gz │ │ │ ├── b8009c2eea665fd068ac70bb6f4eea38.json.gz │ │ │ ├── bc556d437a34c76cdaf6a557e10d4a9c.json.gz │ │ │ ├── be8efffba91634d53d2f1e5c17e80f8d.json.gz │ │ │ ├── c128e94a0afaf8ac8d954c6a80e8fe25.json.gz │ │ │ ├── cc55169f6086f91964754ff124d94364.json.gz │ │ │ ├── d0d285ecad14f2f5408f7235f3bb9ae7.json.gz │ │ │ ├── d2e9beaa2e6663420d998d994c12d922.json.gz │ │ │ ├── d58d8044abf1acca2269abe198171dd8.json.gz │ │ │ ├── d6e5ba5b787bf17645d242f4a7db6457.json.gz │ │ │ ├── de6149693ef4a7dcb5bf67b0b9e8499f.json.gz │ │ │ ├── e01f008e984bef3e25d9fa703b83928a.json.gz │ │ │ ├── e185f5c5beef74a996db845d1c03460e.json.gz │ │ │ ├── e707f7ced500a79df5536a72100500ae.json.gz │ │ │ ├── ebf4938386cbfadfc6a6cd1e5cb74d74.json.gz │ │ │ ├── f1f7db1a5943939763519884346c1032.json.gz │ │ │ ├── fa252d6382ab99caef06eb55a5d9aa43.json.gz │ │ │ └── fcb7452f131057905f8fff9f56aaff93.json.gz │ └── umi.ts ├── .prettierignore ├── README.md ├── .prettierrc ├── .umirc.ts ├── typings.d.ts ├── .editorconfig ├── .gitignore ├── tsconfig.json └── package.json ├── doc ├── mock │ └── .gitkeep ├── src │ ├── .components │ │ ├── code │ │ │ ├── Code4.tsx │ │ │ ├── npm.tsx │ │ │ ├── Code0.tsx │ │ │ ├── index.tsx │ │ │ ├── Code2.tsx │ │ │ ├── Code1.tsx │ │ │ └── Code3.tsx │ │ ├── index.tsx │ │ ├── Footer.tsx │ │ ├── Code.tsx │ │ ├── Background.tsx │ │ └── api │ │ │ ├── Layout.tsx │ │ │ ├── Widget.tsx │ │ │ └── index.tsx │ ├── components │ │ ├── code │ │ │ ├── npm.tsx │ │ │ ├── download.tsx │ │ │ ├── Code0.tsx │ │ │ ├── Code2.tsx │ │ │ ├── index.tsx │ │ │ ├── Code4.tsx │ │ │ ├── Code1.tsx │ │ │ └── Code3.tsx │ │ ├── index.tsx │ │ ├── Footer.tsx │ │ ├── Code.tsx │ │ ├── Background.tsx │ │ └── api │ │ │ ├── Layout.tsx │ │ │ ├── Ref.tsx │ │ │ ├── Widget.tsx │ │ │ └── index.tsx │ ├── package │ │ ├── dashboard │ │ │ ├── components │ │ │ │ ├── toolbar │ │ │ │ │ ├── style │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── index.less │ │ │ │ │ └── index.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── modal │ │ │ │ │ └── index.tsx │ │ │ ├── service.ts │ │ │ ├── style │ │ │ │ ├── empty.css │ │ │ │ ├── message.css │ │ │ │ ├── spin.css │ │ │ │ ├── modal.css │ │ │ │ └── tooltip.css │ │ │ ├── utils.tsx │ │ │ └── index.less │ │ ├── index.tsx │ │ ├── widget │ │ │ ├── index.less │ │ │ ├── index.tsx │ │ │ └── utils.tsx │ │ └── utils.tsx │ ├── widgets │ │ ├── clock │ │ │ ├── snapshot.png │ │ │ ├── index.tsx │ │ │ ├── index.less │ │ │ └── component.tsx │ │ ├── column │ │ │ ├── snapshot.png │ │ │ ├── data.ts │ │ │ ├── index.tsx │ │ │ ├── index.less │ │ │ └── component.tsx │ │ ├── guide │ │ │ ├── snapshot.png │ │ │ ├── index.less │ │ │ ├── index.tsx │ │ │ └── component.tsx │ │ ├── ring │ │ │ ├── snapshot.png │ │ │ ├── data.ts │ │ │ ├── index.tsx │ │ │ ├── index.less │ │ │ └── component.tsx │ │ ├── todo │ │ │ ├── snapshot.png │ │ │ ├── index.tsx │ │ │ ├── index.less │ │ │ ├── data.ts │ │ │ └── component.tsx │ │ ├── popular │ │ │ ├── snapshot.png │ │ │ ├── index.tsx │ │ │ ├── index.less │ │ │ ├── component.tsx │ │ │ └── data.ts │ │ └── index.tsx │ ├── pages │ │ ├── intro.tsx │ │ ├── dashboard.tsx │ │ ├── dashboard1.tsx │ │ ├── layout.ts │ │ └── index.less │ └── config.tsx ├── public │ └── logo.png ├── .prettierignore ├── README.md ├── .prettierrc ├── .editorconfig ├── typings.d.ts ├── .gitignore ├── .umirc.ts ├── tsconfig.json └── package.json ├── .gitignore ├── .DS_Store ├── snapshot.png ├── docs ├── logo.png ├── static │ ├── snapshot.26fdd089.png │ ├── snapshot.4c1244f8.png │ ├── snapshot.8af33446.png │ ├── snapshot.bb5b70c5.png │ └── snapshot.bbbb93bf.png └── index.html ├── .babelrc ├── typings.d.ts ├── .gitpod.yml ├── .eslintrc.js ├── tsconfig.json ├── LICENSE ├── .github └── workflows │ └── main.yml ├── rollup.config.js ├── .vscode └── tasks.json └── package.json /.npmignore: -------------------------------------------------------------------------------- 1 | doc -------------------------------------------------------------------------------- /demo/mock/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/mock/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/src/.components/code/Code4.tsx: -------------------------------------------------------------------------------- 1 | export default ` 2 | 3 | `; 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | build 4 | lib 5 | netlify 6 | .DS_Store -------------------------------------------------------------------------------- /demo/src/pages/index.less: -------------------------------------------------------------------------------- 1 | .title { 2 | background: rgb(121, 242, 157); 3 | } 4 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/.DS_Store -------------------------------------------------------------------------------- /doc/src/components/code/npm.tsx: -------------------------------------------------------------------------------- 1 | export default `npm i react-dashboard-pro -S 2 | `; 3 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/components/toolbar/style/index.ts: -------------------------------------------------------------------------------- 1 | import './index.less'; 2 | -------------------------------------------------------------------------------- /snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/snapshot.png -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/docs/logo.png -------------------------------------------------------------------------------- /doc/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/doc/public/logo.png -------------------------------------------------------------------------------- /demo/src/widgets/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/src/widgets/1.jpg -------------------------------------------------------------------------------- /doc/src/package/dashboard/components/index.tsx: -------------------------------------------------------------------------------- 1 | 2 | import Toolbar from './toolbar' 3 | 4 | export { Toolbar } 5 | 6 | -------------------------------------------------------------------------------- /demo/.umi/core/polyfill.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import 'core-js'; 3 | import 'regenerator-runtime/runtime'; 4 | export {}; 5 | -------------------------------------------------------------------------------- /demo/.umi/core/umiExports.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | export { history } from './history'; 3 | export { plugin } from './plugin'; 4 | -------------------------------------------------------------------------------- /demo/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.md 2 | **/*.svg 3 | **/*.ejs 4 | **/*.html 5 | package.json 6 | .umi 7 | .umi-production 8 | .umi-test 9 | -------------------------------------------------------------------------------- /demo/.umi/core/pluginRegister.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { plugin } from './plugin'; 3 | 4 | 5 | export const __mfsu = 1; 6 | -------------------------------------------------------------------------------- /doc/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.md 2 | **/*.svg 3 | **/*.ejs 4 | **/*.html 5 | package.json 6 | .umi 7 | .umi-production 8 | .umi-test 9 | -------------------------------------------------------------------------------- /doc/src/package/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './dashboard' 2 | import Dashboard from './dashboard' 3 | export default Dashboard 4 | 5 | -------------------------------------------------------------------------------- /demo/src/widgets/clock/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/src/widgets/clock/snapshot.png -------------------------------------------------------------------------------- /demo/src/widgets/guide/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/src/widgets/guide/snapshot.png -------------------------------------------------------------------------------- /demo/src/widgets/ring/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/src/widgets/ring/snapshot.png -------------------------------------------------------------------------------- /demo/src/widgets/todo/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/src/widgets/todo/snapshot.png -------------------------------------------------------------------------------- /doc/src/widgets/clock/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/doc/src/widgets/clock/snapshot.png -------------------------------------------------------------------------------- /doc/src/widgets/column/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/doc/src/widgets/column/snapshot.png -------------------------------------------------------------------------------- /doc/src/widgets/guide/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/doc/src/widgets/guide/snapshot.png -------------------------------------------------------------------------------- /doc/src/widgets/ring/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/doc/src/widgets/ring/snapshot.png -------------------------------------------------------------------------------- /doc/src/widgets/todo/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/doc/src/widgets/todo/snapshot.png -------------------------------------------------------------------------------- /docs/static/snapshot.26fdd089.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/docs/static/snapshot.26fdd089.png -------------------------------------------------------------------------------- /docs/static/snapshot.4c1244f8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/docs/static/snapshot.4c1244f8.png -------------------------------------------------------------------------------- /docs/static/snapshot.8af33446.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/docs/static/snapshot.8af33446.png -------------------------------------------------------------------------------- /docs/static/snapshot.bb5b70c5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/docs/static/snapshot.bb5b70c5.png -------------------------------------------------------------------------------- /docs/static/snapshot.bbbb93bf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/docs/static/snapshot.bbbb93bf.png -------------------------------------------------------------------------------- /demo/src/widgets/column/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/src/widgets/column/snapshot.png -------------------------------------------------------------------------------- /demo/src/widgets/popular/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/src/widgets/popular/snapshot.png -------------------------------------------------------------------------------- /doc/src/widgets/popular/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/doc/src/widgets/popular/snapshot.png -------------------------------------------------------------------------------- /doc/src/components/code/download.tsx: -------------------------------------------------------------------------------- 1 | export default `# 使用cli工具 2 | npm i widgets-cli -D 3 | npx widgets-cli 4 | 5 | # fetchAll下载商店所有部件,fetchOne下载指定部件 6 | `; 7 | -------------------------------------------------------------------------------- /doc/src/.components/code/npm.tsx: -------------------------------------------------------------------------------- 1 | export default `npm i react-dashboard-pro -S 2 | 3 | //下载预设的widget 4 | git clone https://github.com/yuanguandong/react-widgets 5 | `; 6 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["latest", { 4 | "es2015": { 5 | "modules": false 6 | } 7 | }] 8 | ], 9 | "plugins": ["external-helpers"] 10 | } -------------------------------------------------------------------------------- /doc/src/package/widget/index.less: -------------------------------------------------------------------------------- 1 | .react-dashboard-widget { 2 | width: 100%; 3 | height: 100%; 4 | position: relative; 5 | border:1px solid rgba(128,128,128,0.3); 6 | overflow:hidden; 7 | } 8 | -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/09e867201bdb7e28d581abcd4b7d8c14.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/09e867201bdb7e28d581abcd4b7d8c14.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/0ac976858665b23e2ee7127c5b87edf3.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/0ac976858665b23e2ee7127c5b87edf3.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/0f9f9ce9baa523bbc23cadbe85d86873.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/0f9f9ce9baa523bbc23cadbe85d86873.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/11aeb04f5f35e0949f6507c66dbaeb13.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/11aeb04f5f35e0949f6507c66dbaeb13.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/15309499acb061557869b06ee0393973.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/15309499acb061557869b06ee0393973.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/1e4694fef7193a8ee8c86c6838bc5674.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/1e4694fef7193a8ee8c86c6838bc5674.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/26fb2eeb2184b099b392ce7dbfc51cb8.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/26fb2eeb2184b099b392ce7dbfc51cb8.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/2b9e01ec932354f871bb71fcb4936896.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/2b9e01ec932354f871bb71fcb4936896.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/30308bebb1aebf38ff61bae8220a739d.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/30308bebb1aebf38ff61bae8220a739d.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/32f8557a920c90011a2533696d149b4f.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/32f8557a920c90011a2533696d149b4f.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/32ffd9e15066e02886196f859829a235.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/32ffd9e15066e02886196f859829a235.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/42f795da0842c2fd9207ae2f1fe92aac.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/42f795da0842c2fd9207ae2f1fe92aac.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/4950088de873e301fdbbe82ba42feaa8.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/4950088de873e301fdbbe82ba42feaa8.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/4e787fcdccd8283fef47d49a6be85b8d.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/4e787fcdccd8283fef47d49a6be85b8d.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/4f06a6bcb050578d1160df3e2ad79ca5.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/4f06a6bcb050578d1160df3e2ad79ca5.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/51f5b8c3e30c06658dc09f82415eebef.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/51f5b8c3e30c06658dc09f82415eebef.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/57ff7afbe7fe4ce7f53597d795b51e81.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/57ff7afbe7fe4ce7f53597d795b51e81.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/5e671ad88303752645494a4d4831215d.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/5e671ad88303752645494a4d4831215d.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/6717cd3e402d830dcaada2f82eca381f.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/6717cd3e402d830dcaada2f82eca381f.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/69ad0feed2f31abd7d77e81d11a730a2.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/69ad0feed2f31abd7d77e81d11a730a2.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/6b912c10e38a557703d36e1523192cbc.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/6b912c10e38a557703d36e1523192cbc.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/6d477ca635ba3baf6f64693af11fe5ed.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/6d477ca635ba3baf6f64693af11fe5ed.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/79e851082f89733ad62b979814898df3.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/79e851082f89733ad62b979814898df3.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/7aea70718860af13a74a7fc40b75cecf.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/7aea70718860af13a74a7fc40b75cecf.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/856074fab53abc287738a097421113c3.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/856074fab53abc287738a097421113c3.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/8687794b72d1fb1769eb6daadca6ab1a.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/8687794b72d1fb1769eb6daadca6ab1a.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/889ce2be5d70438730885348c1b9c801.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/889ce2be5d70438730885348c1b9c801.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/8e5eb62038961cb9a7a6a1beb1e4f4f8.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/8e5eb62038961cb9a7a6a1beb1e4f4f8.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/95f7dede3dd07cf809f9169637e7b3fe.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/95f7dede3dd07cf809f9169637e7b3fe.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/9626603194f361dd867ce902482c242f.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/9626603194f361dd867ce902482c242f.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/9989483da0ab50d45c1d3d3177e2f658.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/9989483da0ab50d45c1d3d3177e2f658.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/9eba704fff91d2bf1cd82dcf13eccbd1.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/9eba704fff91d2bf1cd82dcf13eccbd1.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/a3b741ceb79e62d12bba554098030622.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/a3b741ceb79e62d12bba554098030622.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/b0c25a98daede2344c53d49aad31eb60.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/b0c25a98daede2344c53d49aad31eb60.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/b1070acee18f868eb3a0e7c7c56e760d.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/b1070acee18f868eb3a0e7c7c56e760d.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/b8009c2eea665fd068ac70bb6f4eea38.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/b8009c2eea665fd068ac70bb6f4eea38.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/bc556d437a34c76cdaf6a557e10d4a9c.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/bc556d437a34c76cdaf6a557e10d4a9c.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/be8efffba91634d53d2f1e5c17e80f8d.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/be8efffba91634d53d2f1e5c17e80f8d.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/c128e94a0afaf8ac8d954c6a80e8fe25.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/c128e94a0afaf8ac8d954c6a80e8fe25.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/cc55169f6086f91964754ff124d94364.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/cc55169f6086f91964754ff124d94364.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/d0d285ecad14f2f5408f7235f3bb9ae7.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/d0d285ecad14f2f5408f7235f3bb9ae7.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/d2e9beaa2e6663420d998d994c12d922.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/d2e9beaa2e6663420d998d994c12d922.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/d58d8044abf1acca2269abe198171dd8.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/d58d8044abf1acca2269abe198171dd8.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/d6e5ba5b787bf17645d242f4a7db6457.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/d6e5ba5b787bf17645d242f4a7db6457.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/de6149693ef4a7dcb5bf67b0b9e8499f.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/de6149693ef4a7dcb5bf67b0b9e8499f.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/e01f008e984bef3e25d9fa703b83928a.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/e01f008e984bef3e25d9fa703b83928a.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/e185f5c5beef74a996db845d1c03460e.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/e185f5c5beef74a996db845d1c03460e.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/e707f7ced500a79df5536a72100500ae.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/e707f7ced500a79df5536a72100500ae.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/ebf4938386cbfadfc6a6cd1e5cb74d74.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/ebf4938386cbfadfc6a6cd1e5cb74d74.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/f1f7db1a5943939763519884346c1032.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/f1f7db1a5943939763519884346c1032.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/fa252d6382ab99caef06eb55a5d9aa43.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/fa252d6382ab99caef06eb55a5d9aa43.json.gz -------------------------------------------------------------------------------- /demo/.umi/.cache/babel-loader/fcb7452f131057905f8fff9f56aaff93.json.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuanguandong/react-dashboard-pro/HEAD/demo/.umi/.cache/babel-loader/fcb7452f131057905f8fff9f56aaff93.json.gz -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | # React Dashboard Pro Demo 2 | 3 | ## Getting Started 4 | 5 | Install dependencies, 6 | 7 | ```bash 8 | $ yarn 9 | ``` 10 | 11 | Start the dev server, 12 | 13 | ```bash 14 | $ yarn start 15 | ``` 16 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # React Dashboard Pro Demo 2 | 3 | ## Getting Started 4 | 5 | Install dependencies, 6 | 7 | ```bash 8 | $ yarn 9 | ``` 10 | 11 | Start the dev server, 12 | 13 | ```bash 14 | $ yarn start 15 | ``` 16 | -------------------------------------------------------------------------------- /demo/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /doc/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /demo/.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | 3 | export default defineConfig({ 4 | nodeModulesTransform: { 5 | type: 'none', 6 | }, 7 | routes: [ 8 | { path: '/', component: '@/pages/index' }, 9 | ], 10 | fastRefresh: {}, 11 | }); 12 | -------------------------------------------------------------------------------- /demo/src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Dashboard from 'react-dashboard-pro'; 3 | import allWidgets from '../widgets'; 4 | 5 | export default () => { 6 | return ( 7 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /demo/src/widgets/index.tsx: -------------------------------------------------------------------------------- 1 | import Clock from './clock'; 2 | import Column from './column'; 3 | import Guide from './guide'; 4 | import Popular from './popular'; 5 | import Ring from './ring'; 6 | import Todo from './todo'; 7 | 8 | export default{ Clock,Guide,Popular,Todo,Column,Ring }; 9 | -------------------------------------------------------------------------------- /doc/src/widgets/index.tsx: -------------------------------------------------------------------------------- 1 | import clock from './clock'; 2 | import column from './column'; 3 | import guide from './guide'; 4 | import popular from './popular'; 5 | import ring from './ring'; 6 | import todo from './todo'; 7 | 8 | export default{ clock,guide,popular,todo,column,ring }; 9 | -------------------------------------------------------------------------------- /doc/src/components/code/Code0.tsx: -------------------------------------------------------------------------------- 1 | export default `import React from 'react'; 2 | import Dashboard from 'react-dashboard-pro'; 3 | import allWidgets from '../widgets'; 4 | 5 | export default () => { 6 | return ( 7 | 10 | ); 11 | }; 12 | `; -------------------------------------------------------------------------------- /demo/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | declare module '*.png'; 4 | declare module '*.svg' { 5 | export function ReactComponent( 6 | props: React.SVGProps, 7 | ): React.ReactElement; 8 | const url: string; 9 | export default url; 10 | } 11 | -------------------------------------------------------------------------------- /doc/src/.components/code/Code0.tsx: -------------------------------------------------------------------------------- 1 | export default `import React from 'react'; 2 | import Dashboard from 'react-dashboard-pro'; 3 | import allWidgets from '../widgets'; 4 | 5 | export default () => { 6 | return ( 7 | 10 | ); 11 | }; 12 | `; -------------------------------------------------------------------------------- /doc/src/.components/code/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as Code0 } from './Code0' 2 | export { default as Code1 } from './Code1' 3 | export { default as Code2 } from './Code2' 4 | export { default as Code3 } from './Code3' 5 | export { default as Code4 } from './Code4' 6 | export { default as Npm } from './npm' 7 | 8 | -------------------------------------------------------------------------------- /demo/src/widgets/README.md: -------------------------------------------------------------------------------- 1 | # react-widgets 2 | react-widgets, 需结合react-dashboard-pro使用,依赖了antd, 使用了ts、less 3 | 4 | 需结合 [react-dashboard-pro](https://github.com/yuanguandong/react-dashboard-pro) 使用 5 | 6 | ![image](https://github.com/yuanguandong/react-widgets/blob/master/1.jpg?raw=true) 7 | 8 | ## todo 9 | ☑️ widget-cli 10 | -------------------------------------------------------------------------------- /doc/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /demo/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /doc/src/.components/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as Api } from './api' 2 | export { default as Api1 } from './api/Layout' 3 | export { default as Api2 } from './api/Widget' 4 | export { default as Background } from './Background' 5 | export { default as Code } from './Code' 6 | export { default as Footer } from './Footer' 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /doc/src/.components/code/Code2.tsx: -------------------------------------------------------------------------------- 1 | export default `export default [ 2 | { 3 | w: 3, 4 | h: 16, 5 | x: 0, 6 | y: 0, 7 | i: 'Popular-81735522335293475546087951289435', 8 | }, 9 | { 10 | w: 3, 11 | h: 11, 12 | x: 3, 13 | y: 5, 14 | i: 'Todo-53084247679600442035440807237732', 15 | } 16 | ] 17 | `; 18 | 19 | -------------------------------------------------------------------------------- /doc/src/components/code/Code2.tsx: -------------------------------------------------------------------------------- 1 | export default `export default [ 2 | { 3 | w: 3, 4 | h: 16, 5 | x: 0, 6 | y: 0, 7 | i: 'Popular-81735522335293475546087951289435', 8 | }, 9 | { 10 | w: 3, 11 | h: 11, 12 | x: 3, 13 | y: 5, 14 | i: 'Todo-53084247679600442035440807237732', 15 | } 16 | ] 17 | `; 18 | 19 | -------------------------------------------------------------------------------- /doc/src/components/code/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as Code0 } from './Code0' 2 | export { default as Code1 } from './Code1' 3 | export { default as Code2 } from './Code2' 4 | export { default as Code3 } from './Code3' 5 | export { default as Code4 } from './Code4' 6 | export { default as Npm } from './npm' 7 | export { default as Download } from './download' 8 | 9 | -------------------------------------------------------------------------------- /typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | declare module '*.png'; 4 | declare module 'react-grid-layout' 5 | declare module '@ant-design/charts' 6 | declare module '*.svg' { 7 | export function ReactComponent( 8 | props: React.SVGProps, 9 | ): React.ReactElement; 10 | const url: string; 11 | export default url; 12 | } 13 | -------------------------------------------------------------------------------- /doc/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | declare module '*.png'; 4 | declare module 'react-grid-layout' 5 | declare module '@ant-design/charts' 6 | declare module '*.svg' { 7 | export function ReactComponent( 8 | props: React.SVGProps, 9 | ): React.ReactElement; 10 | const url: string; 11 | export default url; 12 | } 13 | -------------------------------------------------------------------------------- /demo/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | 16 | # umi 17 | /src/.umi 18 | /src/.umi-production 19 | /src/.umi-test 20 | /.env.local 21 | -------------------------------------------------------------------------------- /demo/.umi/core/plugin.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { Plugin } from '/Users/yuanguandong/Desktop/github/react-dashboard-pro/node_modules/.pnpm/@umijs+runtime@3.5.20_react@16.14.0/node_modules/@umijs/runtime'; 3 | 4 | const plugin = new Plugin({ 5 | validKeys: ['modifyClientRenderOpts','patchRoutes','rootContainer','render','onRouteChange','__mfsu',], 6 | }); 7 | 8 | export { plugin }; 9 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | 16 | # umi 17 | /src/.umi 18 | /src/.umi-production 19 | /src/.umi-test 20 | /.env.local 21 | -------------------------------------------------------------------------------- /doc/src/components/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as Api } from './api' 2 | export { default as Api1 } from './api/Layout' 3 | export { default as Api2 } from './api/Widget' 4 | export { default as RefAPI } from './api/Ref' 5 | export { default as Background } from './Background' 6 | export { default as Code } from './Code' 7 | export { default as Footer } from './Footer' 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | # This configuration file was automatically generated by Gitpod. 2 | # Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file) 3 | # and commit this file to your remote git repository to share the goodness with others. 4 | 5 | tasks: 6 | - init: npm install 7 | command: npm run start 8 | vscode: 9 | extensions: 10 | - dbaeumer.vscode-eslint 11 | 12 | -------------------------------------------------------------------------------- /demo/src/widgets/guide/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Guide'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | background: linear-gradient(to right, #f52248 0%, #e4620c 100%); 8 | padding:20px; 9 | &-title{font-size:24px; font-weight:bold; color:#fff;} 10 | &-content{ color:#fff;} 11 | &-button{ color:#f52248; margin-top:20px;} 12 | } 13 | -------------------------------------------------------------------------------- /doc/src/pages/intro.tsx: -------------------------------------------------------------------------------- 1 | import { Typography } from 'antd'; 2 | const { Title, Paragraph, Text, Link } = Typography; 3 | 4 | export default () => { 5 | return ( 6 | 7 | 开箱即用的一站式仪表板解决方案 8 | 只需简单几步即可拥有动态仪表板功能 9 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /doc/src/widgets/guide/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Guide'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | background: linear-gradient(to right, #f52248 0%, #e4620c 100%); 8 | padding:20px; 9 | &-title{font-size:24px; font-weight:bold; color:#fff;} 10 | &-content{ color:#fff;} 11 | &-button{ color:#f52248; margin-top:20px;} 12 | } 13 | -------------------------------------------------------------------------------- /doc/src/config.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { RiDashboardFill } from 'react-icons/ri' 3 | 4 | export default { 5 | name:'React Dashobard Pro', 6 | packageName:'react-dashboard-pro', 7 | authorHomePage:'https://github.com/yuanguandong', 8 | homePageUrl: 'https://github.com/yuanguandong/react-dashboard-pro', 9 | symbol:, 10 | widgetRepository:'https://github.com/yuanguandong/react-widgets' 11 | } -------------------------------------------------------------------------------- /doc/src/package/dashboard/components/modal/index.tsx: -------------------------------------------------------------------------------- 1 | export default () => { 2 | return ( 3 | <> 4 | 5 |
6 | 7 |
8 | 9 | 10 |
11 |
12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /doc/src/components/code/Code4.tsx: -------------------------------------------------------------------------------- 1 | export default `import React,{useRef} from 'react'; 2 | import Dashboard from 'react-dashboard-pro'; 3 | import allWidgets from '../widgets'; 4 | 5 | export default () => { 6 | const ref = useRef() 7 | const addWidget = ()=>{ 8 | ref.current.addWidget('Todo-1234567') 9 | } 10 | return (<> 11 | 15 | 16 | 17 | ); 18 | }; 19 | `; 20 | -------------------------------------------------------------------------------- /demo/src/widgets/ring/data.ts: -------------------------------------------------------------------------------- 1 | export const List = [ 2 | { 3 | type: 'java', 4 | sales: 38, 5 | }, 6 | { 7 | type: 'c', 8 | sales: 52, 9 | }, 10 | { 11 | type: 'c++', 12 | sales: 61, 13 | }, 14 | { 15 | type: 'javascript', 16 | sales: 145, 17 | }, 18 | { 19 | type: 'php', 20 | sales: 48, 21 | }, 22 | { 23 | type: 'ruby', 24 | sales: 38, 25 | }, 26 | { 27 | type: 'nodejs', 28 | sales: 38, 29 | }, 30 | { 31 | type: 'go', 32 | sales: 38, 33 | }, 34 | ]; -------------------------------------------------------------------------------- /doc/src/widgets/column/data.ts: -------------------------------------------------------------------------------- 1 | export const List = [ 2 | { 3 | type: 'java', 4 | sales: 38, 5 | }, 6 | { 7 | type: 'c', 8 | sales: 52, 9 | }, 10 | { 11 | type: 'c++', 12 | sales: 61, 13 | }, 14 | { 15 | type: 'javascript', 16 | sales: 145, 17 | }, 18 | { 19 | type: 'php', 20 | sales: 48, 21 | }, 22 | { 23 | type: 'ruby', 24 | sales: 38, 25 | }, 26 | { 27 | type: 'nodejs', 28 | sales: 38, 29 | }, 30 | { 31 | type: 'go', 32 | sales: 38, 33 | }, 34 | ]; -------------------------------------------------------------------------------- /doc/src/widgets/ring/data.ts: -------------------------------------------------------------------------------- 1 | export const List = [ 2 | { 3 | type: 'java', 4 | sales: 38, 5 | }, 6 | { 7 | type: 'c', 8 | sales: 52, 9 | }, 10 | { 11 | type: 'c++', 12 | sales: 61, 13 | }, 14 | { 15 | type: 'javascript', 16 | sales: 145, 17 | }, 18 | { 19 | type: 'php', 20 | sales: 48, 21 | }, 22 | { 23 | type: 'ruby', 24 | sales: 38, 25 | }, 26 | { 27 | type: 'nodejs', 28 | sales: 38, 29 | }, 30 | { 31 | type: 'go', 32 | sales: 38, 33 | }, 34 | ]; -------------------------------------------------------------------------------- /demo/src/widgets/column/data.ts: -------------------------------------------------------------------------------- 1 | export const List = [ 2 | { 3 | type: 'java', 4 | sales: 38, 5 | }, 6 | { 7 | type: 'c', 8 | sales: 52, 9 | }, 10 | { 11 | type: 'c++', 12 | sales: 61, 13 | }, 14 | { 15 | type: 'javascript', 16 | sales: 145, 17 | }, 18 | { 19 | type: 'php', 20 | sales: 48, 21 | }, 22 | { 23 | type: 'ruby', 24 | sales: 38, 25 | }, 26 | { 27 | type: 'nodejs', 28 | sales: 38, 29 | }, 30 | { 31 | type: 'go', 32 | sales: 38, 33 | }, 34 | ]; -------------------------------------------------------------------------------- /doc/src/pages/dashboard.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Dashboard from '../package/dashboard'; 3 | import allWidgets from '../widgets'; 4 | import defaultLayout from './layout'; 5 | 6 | export default () => { 7 | return ( 8 | <> 9 | 14 | 15 | ); 16 | }; 17 | 18 | const widgetWrapStyle = { 19 | borderRadius: 10, 20 | boxShadow: '0 3px 3px rgba(128,128,128,0.2)', 21 | }; 22 | -------------------------------------------------------------------------------- /doc/src/pages/dashboard1.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import type { LayoutsIF } from '../package/dashboard'; 3 | import Dashboard from '../package/dashboard'; 4 | import allWidgets from '../widgets'; 5 | 6 | export default () => { 7 | const [layout, setLayout] = useState([]); 8 | const onLayoutChange = (layout: LayoutsIF) => { 9 | setLayout(layout); 10 | }; 11 | return ( 12 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /doc/src/.components/code/Code1.tsx: -------------------------------------------------------------------------------- 1 | export default `import React, { useState } from 'react'; 2 | import type { LayoutsIF } from 'react-dashboard-pro'; 3 | import Dashboard from 'react-dashboard-pro'; 4 | import allWidgets from '../widgets'; 5 | 6 | export default () => { 7 | const [layout, setLayout] = useState([]); 8 | const onLayoutChange = (layout: LayoutsIF) => { 9 | setLayout(layout); 10 | }; 11 | return ( 12 | 17 | ); 18 | }; 19 | `; 20 | -------------------------------------------------------------------------------- /doc/src/components/code/Code1.tsx: -------------------------------------------------------------------------------- 1 | export default `import React, { useState } from 'react'; 2 | import type { LayoutsIF } from 'react-dashboard-pro'; 3 | import Dashboard from 'react-dashboard-pro'; 4 | import allWidgets from '../widgets'; 5 | 6 | export default () => { 7 | const [layout, setLayout] = useState([]); 8 | const onLayoutChange = (layout: LayoutsIF) => { 9 | setLayout(layout); 10 | }; 11 | return ( 12 | 17 | ); 18 | }; 19 | `; 20 | -------------------------------------------------------------------------------- /demo/src/widgets/clock/index.tsx: -------------------------------------------------------------------------------- 1 | import { ClockCircleOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'Clock', 7 | description: 'a clock', 8 | tags: ['all','system'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'blue', 15 | size: { 16 | defaultWidth: 4, 17 | defaultHeight: 5, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /demo/src/widgets/column/index.tsx: -------------------------------------------------------------------------------- 1 | import { BarChartOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'Column', 7 | description: 'column chart', 8 | tags: ['all','chart'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: '#f00', 15 | size: { 16 | defaultWidth: 6, 17 | defaultHeight: 11, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /doc/.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | 3 | let { BASE } = process.env; 4 | 5 | console.log(BASE) 6 | 7 | export default defineConfig({ 8 | hash: true, 9 | favicon: './logo.png', 10 | publicPath: BASE, 11 | base: BASE, 12 | nodeModulesTransform: { 13 | type: 'none', 14 | }, 15 | antd: {}, 16 | devtool: 'source-map', 17 | routes: [ 18 | { path: '/', component: '@/pages/index' }, 19 | { path: '/widget', component: '@/pages/dashboard' }, 20 | ], 21 | // fastRefresh: {}, 22 | outputPath: BASE === '/' ? '../netlify' : '../docs', 23 | // mfsu:{} 24 | }); 25 | -------------------------------------------------------------------------------- /doc/src/widgets/clock/index.tsx: -------------------------------------------------------------------------------- 1 | import { ClockCircleOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'clock', 7 | description: 'a clock', 8 | tags: ['all', 'system'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'blue', 15 | size: { 16 | defaultWidth: 4, 17 | defaultHeight: 5, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /doc/src/widgets/column/index.tsx: -------------------------------------------------------------------------------- 1 | import { BarChartOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'column', 7 | description: 'column chart', 8 | tags: ['all', 'chart'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: '#f00', 15 | size: { 16 | defaultWidth: 6, 17 | defaultHeight: 11, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /demo/src/widgets/ring/index.tsx: -------------------------------------------------------------------------------- 1 | import { IssuesCloseOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'Ring', 7 | description: 'ring progress', 8 | tags: ['all','chart'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'orange', 15 | size: { 16 | defaultWidth: 2, 17 | defaultHeight: 5, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /doc/src/widgets/ring/index.tsx: -------------------------------------------------------------------------------- 1 | import { IssuesCloseOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'ring', 7 | description: 'ring progress', 8 | tags: ['all', 'chart'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'orange', 15 | size: { 16 | defaultWidth: 2, 17 | defaultHeight: 5, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /demo/src/widgets/popular/index.tsx: -------------------------------------------------------------------------------- 1 | import { OrderedListOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'Popular', 7 | description: 'PopularList', 8 | tags: ['all','list'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'green', 15 | size: { 16 | defaultWidth: 3, 17 | defaultHeight: 16, 18 | maxWidth: 12, 19 | maxHeight: 20, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /doc/src/widgets/popular/index.tsx: -------------------------------------------------------------------------------- 1 | import { OrderedListOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'popular', 7 | description: 'PopularList', 8 | tags: ['all', 'list'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'green', 15 | size: { 16 | defaultWidth: 3, 17 | defaultHeight: 16, 18 | maxWidth: 12, 19 | maxHeight: 20, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /demo/src/widgets/todo/index.tsx: -------------------------------------------------------------------------------- 1 | import { CalendarOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'Todo', 7 | description: 'todo list', 8 | tags: ['all','list'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'linear-gradient(-20deg, #b721ff 0%, #21d4fd 100%)', 15 | size: { 16 | defaultWidth: 3, 17 | defaultHeight: 11, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /doc/src/widgets/todo/index.tsx: -------------------------------------------------------------------------------- 1 | import { CalendarOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'todo', 7 | description: 'todo list', 8 | tags: ['all', 'list'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'linear-gradient(-20deg, #b721ff 0%, #21d4fd 100%)', 15 | size: { 16 | defaultWidth: 3, 17 | defaultHeight: 11, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /demo/src/widgets/guide/index.tsx: -------------------------------------------------------------------------------- 1 | import { RightCircleOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'Guide', 7 | description: 'Guide panel, navigation', 8 | tags: ['all','panel'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'linear-gradient(to right, #f52248 0%, #e4620c 100%)', 15 | size: { 16 | defaultWidth: 4, 17 | defaultHeight: 5, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /doc/src/widgets/guide/index.tsx: -------------------------------------------------------------------------------- 1 | import { RightCircleOutlined } from '@ant-design/icons'; 2 | import Panel from './component'; 3 | import snapShot from './snapshot.png'; 4 | 5 | export default { 6 | name: 'guide', 7 | description: 'Guide panel, navigation', 8 | tags: ['all', 'panel'], 9 | component: Panel, 10 | configComponent: null, 11 | maxLength: 2, 12 | snapShot, 13 | icon: , 14 | iconBackground: 'linear-gradient(to right, #f52248 0%, #e4620c 100%)', 15 | size: { 16 | defaultWidth: 4, 17 | defaultHeight: 5, 18 | maxWidth: 12, 19 | maxHeight: 16, 20 | minWidth: 2, 21 | minHeight: 4, 22 | }, 23 | } -------------------------------------------------------------------------------- /demo/src/widgets/ring/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Ring'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | background: var(--component-background); 8 | padding: 20px; 9 | &-title-wrap{ 10 | display:flex; 11 | justify-content:space-between; 12 | } 13 | &-title { 14 | font-size: 24px; 15 | font-weight: bold; 16 | color: var(--text-color); 17 | 18 | } 19 | &-content { 20 | color: rgba(128,128,128,0.7); 21 | } 22 | &-item{ 23 | padding:20px 0; 24 | border-bottom:1px solid rgba(128,128,128,0.2); 25 | &:last-child{border:none;} 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /doc/src/widgets/ring/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Ring'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | background: var(--component-background); 8 | padding: 20px; 9 | &-title-wrap{ 10 | display:flex; 11 | justify-content:space-between; 12 | } 13 | &-title { 14 | font-size: 24px; 15 | font-weight: bold; 16 | color: var(--text-color); 17 | 18 | } 19 | &-content { 20 | color: rgba(128,128,128,0.7); 21 | } 22 | &-item{ 23 | padding:20px 0; 24 | border-bottom:1px solid rgba(128,128,128,0.2); 25 | &:last-child{border:none;} 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /demo/src/widgets/column/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Column'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | background: var(--component-background); 8 | padding: 20px; 9 | &-title-wrap{ 10 | display:flex; 11 | justify-content:space-between; 12 | } 13 | &-title { 14 | font-size: 24px; 15 | font-weight: bold; 16 | color: var(--text-color); 17 | 18 | } 19 | &-content { 20 | color: rgba(128,128,128,0.7); 21 | } 22 | &-item{ 23 | padding:20px 0; 24 | border-bottom:1px solid rgba(128,128,128,0.2); 25 | &:last-child{border:none;} 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /doc/src/widgets/column/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Column'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | background: var(--component-background); 8 | padding: 20px; 9 | &-title-wrap{ 10 | display:flex; 11 | justify-content:space-between; 12 | } 13 | &-title { 14 | font-size: 24px; 15 | font-weight: bold; 16 | color: var(--text-color); 17 | 18 | } 19 | &-content { 20 | color: rgba(128,128,128,0.7); 21 | } 22 | &-item{ 23 | padding:20px 0; 24 | border-bottom:1px solid rgba(128,128,128,0.2); 25 | &:last-child{border:none;} 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const resolve = _path => path.resolve(__dirname, _path) 3 | const DOMGlobals = ['window', 'document'] 4 | const NodeGlobals = ['module', 'require'] 5 | 6 | 7 | module.exports = { 8 | env: { 9 | browser: true, 10 | es6: true 11 | }, 12 | parser: '@typescript-eslint/parser', // 配置ts解析器 13 | parserOptions: { 14 | project: resolve('./tsconfig.json'), 15 | tsconfigRootDir: resolve('./'), 16 | sourceType: 'module' 17 | }, 18 | // plugins: ['prettier'], 19 | rules: { 20 | 'indent': 'off', 21 | 'no-unused-vars': 'off', 22 | 'no-restricted-globals': 'off', 23 | 'no-console': 'off', 24 | } 25 | }; -------------------------------------------------------------------------------- /demo/.umi/core/history.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { createBrowserHistory, History } from '/Users/yuanguandong/Desktop/github/react-dashboard-pro/node_modules/.pnpm/@umijs+runtime@3.5.20_react@16.14.0/node_modules/@umijs/runtime'; 3 | 4 | let options = { 5 | "basename": "/" 6 | }; 7 | if ((window).routerBase) { 8 | options.basename = (window).routerBase; 9 | } 10 | 11 | // remove initial history because of ssr 12 | let history: History = process.env.__IS_SERVER ? null : createBrowserHistory(options); 13 | export const createHistory = (hotReload = false) => { 14 | if (!hotReload) { 15 | history = createBrowserHistory(options); 16 | } 17 | 18 | return history; 19 | }; 20 | 21 | export { history }; 22 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 14 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /demo/.umi/core/routes.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import React from 'react'; 3 | import { ApplyPluginsType } from '/Users/yuanguandong/Desktop/github/react-dashboard-pro/node_modules/.pnpm/@umijs+runtime@3.5.20_react@16.14.0/node_modules/@umijs/runtime'; 4 | import * as umiExports from './umiExports'; 5 | import { plugin } from './plugin'; 6 | 7 | export function getRoutes() { 8 | const routes = [ 9 | { 10 | "path": "/", 11 | "exact": true, 12 | "component": require('@/pages/index.tsx').default 13 | } 14 | ]; 15 | 16 | // allow user to extend routes 17 | plugin.applyPlugins({ 18 | key: 'patchRoutes', 19 | type: ApplyPluginsType.event, 20 | args: { routes }, 21 | }); 22 | 23 | return routes; 24 | } 25 | -------------------------------------------------------------------------------- /demo/src/widgets/guide/component.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from 'antd'; 2 | import React from 'react'; 3 | import './index.less'; 4 | const widgetName = 'Guide'; 5 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 6 | 7 | const Widget = (props: any) => { 8 | const { height } = props; 9 | return ( 10 |
11 |
Update Your Plan
12 |
13 | You haven’t had an update plan for a long time, it’s time to update 14 |
15 | 16 |
17 | ); 18 | }; 19 | 20 | export default Widget; 21 | -------------------------------------------------------------------------------- /doc/src/widgets/guide/component.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from 'antd'; 2 | import React from 'react'; 3 | import './index.less'; 4 | const widgetName = 'Guide'; 5 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 6 | 7 | const Widget = (props: any) => { 8 | const { height } = props; 9 | return ( 10 |
11 |
Update Your Plan
12 |
13 | You haven’t had an update plan for a long time, it’s time to update 14 |
15 | 16 |
17 | ); 18 | }; 19 | 20 | export default Widget; 21 | -------------------------------------------------------------------------------- /doc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "importHelpers": true, 7 | "jsx": "react-jsx", 8 | "esModuleInterop": true, 9 | "sourceMap": true, 10 | "baseUrl": "./", 11 | "strict": false, 12 | "paths": { 13 | "@/*": ["src/*"], 14 | "@@/*": ["src/.umi/*"] 15 | }, 16 | "allowSyntheticDefaultImports": true 17 | }, 18 | "include": [ 19 | "mock/**/*", 20 | "src/**/*", 21 | "package/**/*", 22 | "config/**/*", 23 | ".umirc.ts", 24 | "typings.d.ts", 25 | ], 26 | "exclude": [ 27 | "node_modules", 28 | "lib", 29 | "es", 30 | "dist", 31 | "typings", 32 | "**/__test__", 33 | "test", 34 | "docs", 35 | "tests" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "resolveJsonModule": true, 7 | "importHelpers": true, 8 | "jsx": "react-jsx", 9 | "esModuleInterop": true, 10 | "sourceMap": true, 11 | "baseUrl": "./", 12 | "strict": true, 13 | "paths": { 14 | "@/*": ["src/*"], 15 | "@@/*": ["src/.umi/*"] 16 | }, 17 | "allowSyntheticDefaultImports": true 18 | }, 19 | "include": [ 20 | "mock/**/*", 21 | "src/**/*", 22 | "config/**/*", 23 | ".umirc.ts", 24 | "typings.d.ts" 25 | ], 26 | "exclude": [ 27 | "node_modules", 28 | "lib", 29 | "es", 30 | "dist", 31 | "typings", 32 | "**/__test__", 33 | "test", 34 | "docs", 35 | "tests" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /doc/src/pages/layout.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | w: 3, 4 | h: 16, 5 | x: 0, 6 | y: 0, 7 | i: 'popular-81735522335293475546087951289435', 8 | }, 9 | { 10 | w: 3, 11 | h: 11, 12 | x: 3, 13 | y: 5, 14 | i: 'todo-53084247679600442035440807237732', 15 | }, 16 | { 17 | w: 3, 18 | h: 5, 19 | x: 7, 20 | y: 0, 21 | i: 'guide-94488587319007026057257701564270', 22 | }, 23 | { 24 | w: 4, 25 | h: 5, 26 | x: 3, 27 | y: 0, 28 | i: 'clock-91762259068903857266015365889488', 29 | }, 30 | { 31 | w: 6, 32 | h: 11, 33 | x: 6, 34 | y: 5, 35 | i: 'column-00186412708682371166740249850082', 36 | }, 37 | { 38 | w: 2, 39 | h: 5, 40 | x: 10, 41 | y: 0, 42 | i: 'ring-86085426727800785417310093605893', 43 | }, 44 | ]; 45 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "outDir": "./lib", // 输出目录 5 | "sourceMap": false, // 是否生成sourceMap 6 | "target": "esnext", // 编译目标 7 | "module": "esnext", // 模块类型 8 | "moduleResolution": "node", 9 | "allowJs": false, // 是否编辑js文件 10 | "strict": false, // 严格模式 11 | "noUnusedLocals": true, // 未使用变量报错 12 | "experimentalDecorators": true, // 启动装饰器 13 | "resolveJsonModule": true, // 加载json 14 | "esModuleInterop": true, 15 | "removeComments": false, // 删除注释 16 | "jsx":"react", 17 | 18 | "declaration": true, // 生成定义文件 19 | "declarationMap": false, // 生成定义sourceMap 20 | "declarationDir": "./lib/types", // 定义文件输出目录 21 | 22 | 23 | "lib": ["esnext", "dom"], // 导入库类型定义 24 | "types": ["node"] // 导入指定类型包 25 | }, 26 | "include": [ 27 | "doc/src/package/*" // 导入目录 28 | ] 29 | } -------------------------------------------------------------------------------- /doc/src/.components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import { GithubOutlined } from '@ant-design/icons'; 2 | import { Typography } from 'antd'; 3 | import Config from '../config'; 4 | const { Title, Paragraph, Text, Link } = Typography; 5 | export default () => { 6 | return ( 7 |
8 | 9 | {Config.name} 10 | If you think it works, please give me a STAR 11 | 12 | Open-source MIT Licensed | Copyright © 2021-present 13 | 14 | 15 | @Yuanguandong 16 | 17 | 18 | 19 | Github 20 | 21 | 22 | 23 |
24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /doc/src/components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import { GithubOutlined } from '@ant-design/icons'; 2 | import { Typography } from 'antd'; 3 | import Config from '../config'; 4 | const { Title, Paragraph, Text, Link } = Typography; 5 | export default () => { 6 | return ( 7 |
8 | 9 | {Config.name} 10 | If you think it works, please give me a STAR 11 | 12 | Open-source MIT Licensed | Copyright © 2021-present 13 | 14 | 15 | @Yuanguandong 16 | 17 | 18 | 19 | Github 20 | 21 | 22 | 23 |
24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/components/toolbar/index.tsx: -------------------------------------------------------------------------------- 1 | import classNames from 'classnames'; 2 | import React from 'react'; 3 | import './style'; 4 | export interface ToolBarPropsIF { 5 | extraLeft?: React.ReactNode; 6 | extraRight?: React.ReactNode; 7 | style?: React.HTMLAttributes; 8 | className?: string; 9 | fixed?: boolean; 10 | } 11 | 12 | const prefixCls = 'react-dashboard-toolbar'; 13 | 14 | const Toolbar = (props: ToolBarPropsIF) => { 15 | const { extraLeft, extraRight, fixed, className, style } = props; 16 | return ( 17 |
18 |
{extraLeft}
19 |
20 |
{extraRight}
21 |
22 | ); 23 | }; 24 | 25 | export default Toolbar; 26 | -------------------------------------------------------------------------------- /doc/src/.components/code/Code3.tsx: -------------------------------------------------------------------------------- 1 | export default ` 2 | // todo/index.tsx 3 | import { CalendarOutlined } from '@ant-design/icons'; 4 | import Panel from './component'; 5 | import snapShot from './snapshot.png'; 6 | 7 | export default { 8 | name: 'Todo', 9 | description: 'todo list', 10 | tags: ['all','list'], 11 | component: Panel, 12 | configComponent: null, 13 | maxLength: 2, 14 | snapShot, 15 | icon: , 16 | iconBackground: 'linear-gradient(-20deg, #b721ff 0%, #21d4fd 100%)', 17 | size: { 18 | defaultWidth: 3, 19 | defaultHeight: 11, 20 | maxWidth: 12, 21 | maxHeight: 16, 22 | minWidth: 2, 23 | minHeight: 4, 24 | }, 25 | } 26 | // **/**.index …… 27 | 28 | // widgets/index.tsx 29 | import Clock from './clock'; 30 | import Column from './column'; 31 | import Guide from './guide'; 32 | import Popular from './popular'; 33 | import Ring from './ring'; 34 | import Todo from './todo'; 35 | 36 | export default{ Clock,Guide,Popular,Todo,Column,Ring }; 37 | `; 38 | 39 | -------------------------------------------------------------------------------- /doc/src/components/code/Code3.tsx: -------------------------------------------------------------------------------- 1 | export default ` 2 | // todo/index.tsx 3 | import { CalendarOutlined } from '@ant-design/icons'; 4 | import Panel from './component'; 5 | import snapShot from './snapshot.png'; 6 | 7 | export default { 8 | name: 'Todo', 9 | description: 'todo list', 10 | tags: ['all','list'], 11 | component: Panel, 12 | configComponent: null, 13 | maxLength: 2, 14 | snapShot, 15 | icon: , 16 | iconBackground: 'linear-gradient(-20deg, #b721ff 0%, #21d4fd 100%)', 17 | size: { 18 | defaultWidth: 3, 19 | defaultHeight: 11, 20 | maxWidth: 12, 21 | maxHeight: 16, 22 | minWidth: 2, 23 | minHeight: 4, 24 | }, 25 | } 26 | // **/**.index …… 27 | 28 | // widgets/index.tsx 29 | import Clock from './clock'; 30 | import Column from './column'; 31 | import Guide from './guide'; 32 | import Popular from './popular'; 33 | import Ring from './ring'; 34 | import Todo from './todo'; 35 | 36 | export default{ Clock,Guide,Popular,Todo,Column,Ring }; 37 | `; 38 | 39 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/components/toolbar/style/index.less: -------------------------------------------------------------------------------- 1 | .react-dashboard-toolbar { 2 | display: flex; 3 | align-items: center; 4 | justify-content: space-between; 5 | // width: 100%; 6 | padding: 0 10px; 7 | padding-bottom: 10px; 8 | // background: var(--component-background); 9 | 10 | &:after { 11 | display: block; 12 | clear: both; 13 | content: ''; 14 | } 15 | 16 | &-left { 17 | float: left; 18 | 19 | button { 20 | margin-right: 10px; 21 | } 22 | } 23 | 24 | &-right { 25 | float: right; 26 | 27 | button { 28 | margin-left: 10px; 29 | } 30 | } 31 | 32 | &-space { 33 | flex: auto; 34 | height: 1px; 35 | margin: 0 !important; 36 | padding: 0 !important; 37 | border: 0 !important; 38 | -webkit-box-flex: 1; 39 | } 40 | 41 | &-fixed { 42 | position: fixed; 43 | right: 0; 44 | bottom: 0; 45 | z-index: 9; 46 | border-top: 1px solid rgba(128, 128, 128, 0.1); 47 | box-shadow: 0 -1px 2px rgba(128, 128, 128, 0.03); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Favori 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /demo/src/widgets/column/component.tsx: -------------------------------------------------------------------------------- 1 | import { Column } from '@ant-design/charts'; 2 | import { EllipsisOutlined } from '@ant-design/icons'; 3 | import { Typography } from 'antd'; 4 | import React from 'react'; 5 | import { List } from './data'; 6 | import './index.less'; 7 | const widgetName = 'Column'; 8 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 9 | const { Title } = Typography; 10 | const Widget = (props: any) => { 11 | const { height } = props; 12 | 13 | const config = { 14 | data: List, 15 | xField: 'type', 16 | yField: 'sales', 17 | padding: [50, 30, 80, 30], 18 | color: '#f52248', 19 | columnStyle: { 20 | radius: [20, 20, 20, 20], 21 | }, 22 | legend: false, 23 | minColumnWidth: 10, 24 | maxColumnWidth: 10, 25 | }; 26 | return ( 27 |
28 |
29 |
{widgetName}
30 | 31 |
32 | 33 |
34 | ); 35 | }; 36 | 37 | export default Widget; 38 | -------------------------------------------------------------------------------- /doc/src/widgets/column/component.tsx: -------------------------------------------------------------------------------- 1 | import { Column } from '@ant-design/charts'; 2 | import { EllipsisOutlined } from '@ant-design/icons'; 3 | import { Typography } from 'antd'; 4 | import React from 'react'; 5 | import { List } from './data'; 6 | import './index.less'; 7 | const widgetName = 'Column'; 8 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 9 | const { Title } = Typography; 10 | const Widget = (props: any) => { 11 | const { height } = props; 12 | 13 | const config = { 14 | data: List, 15 | xField: 'type', 16 | yField: 'sales', 17 | padding: [50, 30, 80, 30], 18 | color: '#f52248', 19 | columnStyle: { 20 | radius: [20, 20, 20, 20], 21 | }, 22 | legend: false, 23 | minColumnWidth: 10, 24 | maxColumnWidth: 10, 25 | }; 26 | return ( 27 |
28 |
29 |
{widgetName}
30 | 31 |
32 | 33 |
34 | ); 35 | }; 36 | 37 | export default Widget; 38 | -------------------------------------------------------------------------------- /demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "umi dev", 5 | "build": "umi build", 6 | "postinstall": "umi generate tmp", 7 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 8 | "test": "umi-test", 9 | "test:coverage": "umi-test --coverage" 10 | }, 11 | "gitHooks": { 12 | "pre-commit": "lint-staged" 13 | }, 14 | "lint-staged": { 15 | "*.{js,jsx,less,md,json}": [ 16 | "prettier --write" 17 | ], 18 | "*.ts?(x)": [ 19 | "prettier --parser=typescript --write" 20 | ] 21 | }, 22 | "dependencies": { 23 | "@ant-design/icons": "^4.7.0", 24 | "@ant-design/pro-layout": "^6.5.0", 25 | "antd": "^4.18.6", 26 | "moment": "^2.29.1", 27 | "react": "17.x", 28 | "react-dashboard-pro": "^1.0.12", 29 | "react-dom": "17.x", 30 | "umi": "^3.5.20" 31 | }, 32 | "devDependencies": { 33 | "@types/react": "^17.0.0", 34 | "@types/react-dom": "^17.0.0", 35 | "@umijs/preset-react": "1.x", 36 | "@umijs/test": "^3.5.20", 37 | "lint-staged": "^10.0.7", 38 | "prettier": "^2.2.0", 39 | "typescript": "^4.1.2", 40 | "yorkie": "^2.0.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /demo/src/widgets/todo/data.ts: -------------------------------------------------------------------------------- 1 | export const List = [{ 2 | title:'Research', 3 | content:'I need 5 docs of the logo', 4 | process:30, 5 | users:[{ 6 | name:'Tom', 7 | avatar:'https://hbimg.huabanimg.com/60a99dbf811d6c4b0918f0e866fbe94c40bef3194458b-wQnWdH_fw658/format/webp' 8 | },{ 9 | name:'John', 10 | avatar:'https://hbimg.huabanimg.com/705b8bd1ef14d6fe357e4acc81b31700e96a466135025-amey79_fw658/format/webp' 11 | },{ 12 | name:'Lucy', 13 | avatar:'https://hbimg.huabanimg.com/69aa5056d378d388eac4a8e41cb6902780b855912d9a0-2Hp392_fw658/format/webp' 14 | }] 15 | },{ 16 | title:'Work on Design System', 17 | content:'Complete the missing items, Ponder over the colors, Make a moodboard', 18 | process:60, 19 | users:[{ 20 | name:'Yoi', 21 | avatar:'https://hbimg.huabanimg.com/393d056b91326dc1d94b24413ab6d12cbf4a49e13459d-p6US6S_fw658/format/webp' 22 | },{ 23 | name:'Pany', 24 | avatar:'https://hbimg.huabanimg.com/1158908ab071ddd63cbc15a902972c2100f4cd5b330f5-nx0dGB_fw658/format/webp' 25 | },{ 26 | name:'Danty', 27 | avatar:'https://hbimg.huabanimg.com/e4a47f5e8d50d7850eb4f2e5ba4ebc686fc2222d25590-TtEQKK_fw658/format/webp' 28 | }] 29 | }] -------------------------------------------------------------------------------- /demo/src/widgets/todo/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Todo'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | background: var(--component-background); 8 | padding: 20px; 9 | overflow-y: auto; 10 | &::-webkit-scrollbar { 11 | width: 1px; 12 | height: 1px; 13 | overflow: auto; 14 | } 15 | 16 | &::-webkit-scrollbar-thumb { 17 | background-color: var(--primary-color); 18 | min-height: 25px; 19 | min-width: 25px; 20 | 21 | &:hover { 22 | background-color: #a8a8a8; 23 | } 24 | 25 | &:active { 26 | background-color: #787878; 27 | } 28 | } 29 | 30 | &::-webkit-scrollbar-track { 31 | background-color: #f7f7f7; 32 | border: 1px solid #efefef; 33 | } 34 | &-title-wrap{ 35 | display:flex; 36 | justify-content:space-between; 37 | } 38 | &-title { 39 | font-size: 24px; 40 | font-weight: bold; 41 | color: var(--text-color); 42 | 43 | } 44 | &-content { 45 | color: rgba(128,128,128,0.7); 46 | } 47 | &-item{ 48 | padding:20px 0; 49 | border-bottom:1px solid rgba(128,128,128,0.2); 50 | &:last-child{border:none;} 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /doc/src/widgets/todo/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Todo'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | background: var(--component-background); 8 | padding: 20px; 9 | overflow-y: auto; 10 | &::-webkit-scrollbar { 11 | width: 1px; 12 | height: 1px; 13 | overflow: auto; 14 | } 15 | 16 | &::-webkit-scrollbar-thumb { 17 | background-color: var(--primary-color); 18 | min-height: 25px; 19 | min-width: 25px; 20 | 21 | &:hover { 22 | background-color: #a8a8a8; 23 | } 24 | 25 | &:active { 26 | background-color: #787878; 27 | } 28 | } 29 | 30 | &::-webkit-scrollbar-track { 31 | background-color: #f7f7f7; 32 | border: 1px solid #efefef; 33 | } 34 | &-title-wrap{ 35 | display:flex; 36 | justify-content:space-between; 37 | } 38 | &-title { 39 | font-size: 24px; 40 | font-weight: bold; 41 | color: var(--text-color); 42 | 43 | } 44 | &-content { 45 | color: rgba(128,128,128,0.7); 46 | } 47 | &-item{ 48 | padding:20px 0; 49 | border-bottom:1px solid rgba(128,128,128,0.2); 50 | &:last-child{border:none;} 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/service.ts: -------------------------------------------------------------------------------- 1 | import { request } from './utils'; 2 | 3 | interface payloadProps { 4 | id: string; 5 | data?: object; 6 | } 7 | 8 | // 获取仪表板信息 9 | export async function fetch(payload: payloadProps) { 10 | const { id } = payload; 11 | let url = '/accountUserSelf/getUserData'; 12 | if (!id) { 13 | return; 14 | } 15 | return request(url, { 16 | method: 'GET', 17 | data: { 18 | dataId: id, 19 | dataType: 'dashboard', 20 | }, 21 | }); 22 | } 23 | 24 | // 修改仪表板信息 25 | export async function update(payload: payloadProps) { 26 | const { id, data } = payload; 27 | let url = '/accountUserSelf/setUserData'; 28 | if (!id) { 29 | return; 30 | } 31 | return request(url, { 32 | method: 'POST', 33 | data: { 34 | dataId: id, 35 | dataType: 'dashboard', 36 | bigData: JSON.stringify(data), 37 | }, 38 | }); 39 | } 40 | 41 | //删除小程序信息 42 | export function removeWidgetApi(params: any) { 43 | const { widgetKey } = params; 44 | let url = '/accountUserSelf/delUserData'; 45 | return request(url, { 46 | method: 'DELETE', 47 | data: { 48 | dataId: widgetKey, 49 | dataType: 'widget', 50 | }, 51 | }); 52 | } 53 | -------------------------------------------------------------------------------- /demo/src/widgets/ring/component.tsx: -------------------------------------------------------------------------------- 1 | import { RingProgress } from '@ant-design/charts'; 2 | import { EllipsisOutlined } from '@ant-design/icons'; 3 | import { Typography } from 'antd'; 4 | import React from 'react'; 5 | import './index.less'; 6 | const widgetName = 'Ring'; 7 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 8 | const { Title } = Typography; 9 | const Widget = (props: any) => { 10 | const { height } = props; 11 | 12 | var config = { 13 | autoFit: true, 14 | percent: 0.6, 15 | color: ['#F4664A', '#E8EDF3'], 16 | innerRadius: 0.8, 17 | radius: 0.98, 18 | statistic: { 19 | title: { 20 | style: { 21 | color: '#363636', 22 | fontSize: '12px', 23 | lineHeight: '14px', 24 | }, 25 | formatter: function formatter() { 26 | return 'Progress'; 27 | }, 28 | }, 29 | }, 30 | }; 31 | 32 | return ( 33 |
34 |
35 |
{widgetName}
36 | 37 |
38 | 39 |
40 | ); 41 | }; 42 | 43 | export default Widget; 44 | -------------------------------------------------------------------------------- /doc/src/widgets/ring/component.tsx: -------------------------------------------------------------------------------- 1 | import { RingProgress } from '@ant-design/charts'; 2 | import { EllipsisOutlined } from '@ant-design/icons'; 3 | import { Typography } from 'antd'; 4 | import React from 'react'; 5 | import './index.less'; 6 | const widgetName = 'Ring'; 7 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 8 | const { Title } = Typography; 9 | const Widget = (props: any) => { 10 | const { height } = props; 11 | 12 | var config = { 13 | autoFit: true, 14 | percent: 0.6, 15 | color: ['#F4664A', '#E8EDF3'], 16 | innerRadius: 0.8, 17 | radius: 0.98, 18 | statistic: { 19 | title: { 20 | style: { 21 | color: '#363636', 22 | fontSize: '12px', 23 | lineHeight: '14px', 24 | }, 25 | formatter: function formatter() { 26 | return 'Progress'; 27 | }, 28 | }, 29 | }, 30 | }; 31 | 32 | return ( 33 |
34 |
35 |
{widgetName}
36 | 37 |
38 | 39 |
40 | ); 41 | }; 42 | 43 | export default Widget; 44 | -------------------------------------------------------------------------------- /doc/src/widgets/todo/data.ts: -------------------------------------------------------------------------------- 1 | export const List = [{ 2 | title:'Research', 3 | content:'I need 5 docs of the logo', 4 | process:30, 5 | users:[{ 6 | name:'Tom', 7 | avatar:'https://cdn.dribbble.com/users/515705/screenshots/15102691/media/f5ec0b25eb7853394cf26f2162b76d8d.jpg?compress=1&resize=40x30' 8 | },{ 9 | name:'John', 10 | avatar:'https://cdn.dribbble.com/users/1338391/screenshots/15386836/media/dea169824f0cce3899c068c35b82205b.jpg?compress=1&resize=40x30' 11 | },{ 12 | name:'Lucy', 13 | avatar:'https://cdn.dribbble.com/users/1355613/screenshots/15234311/media/863e1b6962855907bf7b31f09a4c3eb1.jpg?compress=1&resize=40x30' 14 | }] 15 | },{ 16 | title:'Work on Design System', 17 | content:'Complete the missing items, Ponder over the colors, Make a moodboard', 18 | process:60, 19 | users:[{ 20 | name:'Yoi', 21 | avatar:'https://cdn.dribbble.com/users/1174720/screenshots/15718185/media/b54ee56400b00386f558b6a6f465d5b0.png?compress=1&resize=40x30' 22 | },{ 23 | name:'Pany', 24 | avatar:'https://cdn.dribbble.com/users/721159/screenshots/15220386/media/ea0f2e0fce088e54581039ceeb82212c.png?compress=1&resize=40x30' 25 | },{ 26 | name:'Danty', 27 | avatar:'https://cdn.dribbble.com/users/230875/screenshots/12163492/media/9ccf7b00b9933758d84c8f6b2bf9185f.jpg?compress=1&resize=40x30' 28 | }] 29 | }] -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | push: 9 | branches: [master] 10 | pull_request: 11 | branches: [master] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v2 27 | 28 | # Runs a single command using the runners shell 29 | - name: install 30 | run: cd doc && npm i 31 | 32 | # Runs a set of commands using the runners shell 33 | - name: build:doc 34 | run: cd doc && npm run build:doc 35 | 36 | # 部署到github pages 37 | - name: Deploy to gh-pages 38 | uses: peaceiris/actions-gh-pages@v3 39 | with: 40 | deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }} 41 | publish_dir: ./docs 42 | -------------------------------------------------------------------------------- /demo/.umi/core/devScripts.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | 3 | if (window.g_initWebpackHotDevClient) { 4 | function tryApplyUpdates(onHotUpdateSuccess?: Function) { 5 | // @ts-ignore 6 | if (!module.hot) { 7 | window.location.reload(); 8 | return; 9 | } 10 | 11 | function isUpdateAvailable() { 12 | // @ts-ignore 13 | return window.g_getMostRecentCompilationHash() !== __webpack_hash__; 14 | } 15 | 16 | // TODO: is update available? 17 | // @ts-ignore 18 | if (!isUpdateAvailable() || module.hot.status() !== 'idle') { 19 | return; 20 | } 21 | 22 | function handleApplyUpdates(err: Error | null, updatedModules: any) { 23 | if (err || !updatedModules || window.g_getHadRuntimeError()) { 24 | window.location.reload(); 25 | return; 26 | } 27 | 28 | onHotUpdateSuccess?.(); 29 | 30 | if (isUpdateAvailable()) { 31 | // While we were updating, there was a new update! Do it again. 32 | tryApplyUpdates(); 33 | } 34 | } 35 | 36 | // @ts-ignore 37 | module.hot.check(true).then( 38 | function (updatedModules: any) { 39 | handleApplyUpdates(null, updatedModules); 40 | }, 41 | function (err: Error) { 42 | handleApplyUpdates(err, null); 43 | }, 44 | ); 45 | } 46 | 47 | window.g_initWebpackHotDevClient({ 48 | tryApplyUpdates, 49 | }); 50 | } 51 | 52 | export const __mfsu = 1; 53 | -------------------------------------------------------------------------------- /demo/src/widgets/todo/component.tsx: -------------------------------------------------------------------------------- 1 | import { EllipsisOutlined } from '@ant-design/icons'; 2 | import { Avatar, Progress, Typography } from 'antd'; 3 | import React from 'react'; 4 | import { List } from './data'; 5 | import './index.less'; 6 | const widgetName = 'Todo'; 7 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 8 | const { Title } = Typography; 9 | 10 | const Widget = (props: any) => { 11 | const { height } = props; 12 | return ( 13 |
14 |
15 |
{widgetName}
16 | 17 |
18 | {List.map((item) => ( 19 |
20 | {item.title} 21 |
{item.content}
22 |
progress
23 | 30 | {item.users.map((user) => ( 31 | 32 | ))} 33 |
34 | ))} 35 |
36 | ); 37 | }; 38 | 39 | export default Widget; 40 | -------------------------------------------------------------------------------- /doc/src/widgets/todo/component.tsx: -------------------------------------------------------------------------------- 1 | import { EllipsisOutlined } from '@ant-design/icons'; 2 | import { Avatar, Progress, Typography } from 'antd'; 3 | import React from 'react'; 4 | import { List } from './data'; 5 | import './index.less'; 6 | const widgetName = 'Todo'; 7 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 8 | const { Title } = Typography; 9 | 10 | const Widget = (props: any) => { 11 | const { height } = props; 12 | return ( 13 |
14 |
15 |
{widgetName}
16 | 17 |
18 | {List.map((item) => ( 19 |
20 | {item.title} 21 |
{item.content}
22 |
progress
23 | 30 | {item.users.map((user) => ( 31 | 32 | ))} 33 |
34 | ))} 35 |
36 | ); 37 | }; 38 | 39 | export default Widget; 40 | -------------------------------------------------------------------------------- /doc/src/package/widget/index.tsx: -------------------------------------------------------------------------------- 1 | import classnames from 'classnames'; 2 | import _ from 'lodash'; 3 | import React, { useState } from 'react'; 4 | import './index.less'; 5 | import { ConfigBar } from './utils'; 6 | interface WidgetProps { 7 | widgets: any; 8 | widgetKey: string; 9 | widgetType: string; 10 | height: number; 11 | editMode: boolean; 12 | onDeleteWidget?: Function; 13 | [key: string]: any; 14 | } 15 | 16 | //widget渲染器 17 | const Widget = (props: WidgetProps) => { 18 | const { 19 | widgets, 20 | widgetKey, 21 | widgetType, 22 | editMode, 23 | onDeleteWidget, 24 | widgetWrapClassName, 25 | widgetWrapStyle, 26 | } = props; 27 | const [configShow, setConfigShow] = useState(false); 28 | const component = _.get(widgets, widgetType + '.component'); 29 | const configComponent = _.get(widgets, widgetType + '.configComponent'); 30 | return ( 31 |
35 | {component && 36 | React.createElement(component, { 37 | ...props, 38 | })} 39 | 46 | {configComponent && 47 | React.createElement(configComponent, { 48 | ...props, 49 | visible: configShow, 50 | setVisible: setConfigShow, 51 | })} 52 |
53 | ); 54 | }; 55 | 56 | export default Widget; 57 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import commonjs from "rollup-plugin-commonjs"; // commonjs模块转换插件 3 | import { eslint } from "rollup-plugin-eslint"; // eslint插件 4 | import resolve from "rollup-plugin-node-resolve"; // 依赖引用插件 5 | import postcss from "rollup-plugin-postcss"; 6 | import ts from "rollup-plugin-typescript2"; 7 | import { uglify } from "rollup-plugin-uglify"; 8 | import packageJSON from "./package.json"; 9 | const getPath = (_path) => path.resolve(__dirname, _path); 10 | 11 | const extensions = [".js", ".ts", ".tsx"]; 12 | 13 | // ts 14 | const tsPlugin = ts({ 15 | tsconfig: getPath("./tsconfig.json"), // 导入本地ts配置 16 | extensions, 17 | }); 18 | 19 | // eslint 20 | const esPlugin = eslint({ 21 | throwOnError: true, 22 | include: ["src/**/*.ts"], 23 | exclude: ["node_modules/**", "lib/**"], 24 | }); 25 | 26 | // 基础配置 27 | const commonConf = { 28 | input: getPath("./doc/src/package/index.tsx"), 29 | external: ["react","react-dom","antd","@ant-design/icons","react-grid-layout"], 30 | plugins: [ 31 | uglify(), 32 | postcss(), 33 | resolve(extensions), 34 | // babel({ 35 | // exclude: 'node_modules/**' // 仅仅转译我们的源码 36 | // }), 37 | commonjs(), 38 | esPlugin, 39 | tsPlugin, 40 | 41 | ], 42 | }; 43 | 44 | export default [ 45 | { 46 | ...commonConf, 47 | output: { 48 | name: packageJSON.name, 49 | file: packageJSON.main, // 通用模块 50 | format: "umd", 51 | }, 52 | }, 53 | { 54 | ...commonConf, 55 | output: { 56 | name: packageJSON.name, 57 | file: packageJSON.module, // es6模块 58 | format: "es", 59 | }, 60 | } 61 | ]; 62 | -------------------------------------------------------------------------------- /doc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "umi dev", 5 | "build:netlify": "BASE=/ umi build", 6 | "build:doc": "BASE=/react-dashboard-pro/ umi build", 7 | "postinstall": "umi generate tmp", 8 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 9 | "test": "umi-test", 10 | "test:coverage": "umi-test --coverage" 11 | }, 12 | "gitHooks": { 13 | "pre-commit": "lint-staged" 14 | }, 15 | "lint-staged": { 16 | "*.{js,jsx,less,md,json}": [ 17 | "prettier --write" 18 | ], 19 | "*.ts?(x)": [ 20 | "prettier --parser=typescript --write" 21 | ] 22 | }, 23 | "dependencies": { 24 | "@ant-design/charts": "^1.2.10", 25 | "@ant-design/icons": "^4.7.0", 26 | "@ant-design/pro-layout": "^6.5.0", 27 | "@emotion/react": "^11.4.1", 28 | "@emotion/styled": "^11.3.0", 29 | "@umijs/preset-react": "1.x", 30 | "classnames": "^2.3.1", 31 | "lodash": "^4.17.21", 32 | "modal-g": "^0.1.35", 33 | "moment": "^2.29.1", 34 | "react-grid-layout": "^1.3.0", 35 | "react-icons": "^4.2.0", 36 | "react-keyevent": "^1.0.9", 37 | "react-resize-detector": "^6.7.6", 38 | "react-syntax-highlighter": "^15.4.3", 39 | "smart-background": "^1.0.8", 40 | "umi": "^3.5.2" 41 | }, 42 | "devDependencies": { 43 | "@types/lodash": "^4.14.172", 44 | "@types/react": "^17.0.0", 45 | "@types/react-dom": "^17.0.0", 46 | "@umijs/test": "^3.5.2", 47 | "lint-staged": "^10.0.7", 48 | "prettier": "^2.2.0", 49 | "react": "17.x", 50 | "react-dom": "17.x", 51 | "typescript": "^4.1.2", 52 | "yorkie": "^2.0.0" 53 | }, 54 | "__npminstall_done": false 55 | } 56 | -------------------------------------------------------------------------------- /doc/src/.components/Code.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Collapse } from 'antd'; 2 | import { useState } from 'react'; 3 | import { FaCode } from 'react-icons/fa'; 4 | import { Light as SyntaxHighlighter } from 'react-syntax-highlighter'; 5 | import bash from 'react-syntax-highlighter/dist/esm/languages/hljs/bash'; 6 | import typescript from 'react-syntax-highlighter/dist/esm/languages/hljs/typescript'; 7 | import { atomOneDark } from 'react-syntax-highlighter/dist/esm/styles/hljs'; 8 | const { Panel } = Collapse; 9 | 10 | SyntaxHighlighter.registerLanguage('javascript', typescript); 11 | SyntaxHighlighter.registerLanguage('bash', bash); 12 | 13 | export default (props: any) => { 14 | const { content, defaultOpen = false, title = '代码示例',type='typescript' } = props; 15 | 16 | const [show, setShow] = useState(defaultOpen); 17 | 18 | return ( 19 |
20 | 39 | {show && ( 40 | 46 | {content} 47 | 48 | )} 49 |
50 | ); 51 | }; 52 | -------------------------------------------------------------------------------- /doc/src/components/Code.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Collapse } from 'antd'; 2 | import { useState } from 'react'; 3 | import { FaCode } from 'react-icons/fa'; 4 | import { Light as SyntaxHighlighter } from 'react-syntax-highlighter'; 5 | import bash from 'react-syntax-highlighter/dist/esm/languages/hljs/bash'; 6 | import typescript from 'react-syntax-highlighter/dist/esm/languages/hljs/typescript'; 7 | import { atomOneDark } from 'react-syntax-highlighter/dist/esm/styles/hljs'; 8 | const { Panel } = Collapse; 9 | 10 | SyntaxHighlighter.registerLanguage('javascript', typescript); 11 | SyntaxHighlighter.registerLanguage('bash', bash); 12 | 13 | export default (props: any) => { 14 | const { content, defaultOpen = false, title = '代码示例',type='typescript' } = props; 15 | 16 | const [show, setShow] = useState(defaultOpen); 17 | 18 | return ( 19 |
20 | 39 | {show && ( 40 | 46 | {content} 47 | 48 | )} 49 |
50 | ); 51 | }; 52 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/style/empty.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */ 2 | /* stylelint-disable no-duplicate-selectors */ 3 | /* stylelint-disable */ 4 | /* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */ 5 | .ant-empty { 6 | margin: 0 8px; 7 | font-size: 14px; 8 | line-height: 1.5715; 9 | text-align: center; 10 | } 11 | .ant-empty-image { 12 | height: 100px; 13 | margin-bottom: 8px; 14 | } 15 | .ant-empty-image img { 16 | height: 100%; 17 | } 18 | .ant-empty-image svg { 19 | height: 100%; 20 | margin: auto; 21 | } 22 | .ant-empty-footer { 23 | margin-top: 16px; 24 | } 25 | .ant-empty-normal { 26 | margin: 32px 0; 27 | color: rgba(0, 0, 0, 0.25); 28 | } 29 | .ant-empty-normal .ant-empty-image { 30 | height: 40px; 31 | } 32 | .ant-empty-small { 33 | margin: 8px 0; 34 | color: rgba(0, 0, 0, 0.25); 35 | } 36 | .ant-empty-small .ant-empty-image { 37 | height: 35px; 38 | } 39 | .ant-empty-img-default-ellipse { 40 | fill: #f5f5f5; 41 | fill-opacity: 0.8; 42 | } 43 | .ant-empty-img-default-path-1 { 44 | fill: #aeb8c2; 45 | } 46 | .ant-empty-img-default-path-2 { 47 | fill: url(#linearGradient-1); 48 | } 49 | .ant-empty-img-default-path-3 { 50 | fill: #f5f5f7; 51 | } 52 | .ant-empty-img-default-path-4 { 53 | fill: #dce0e6; 54 | } 55 | .ant-empty-img-default-path-5 { 56 | fill: #dce0e6; 57 | } 58 | .ant-empty-img-default-g { 59 | fill: #fff; 60 | } 61 | .ant-empty-img-simple-ellipse { 62 | fill: #f5f5f5; 63 | } 64 | .ant-empty-img-simple-g { 65 | stroke: #d9d9d9; 66 | } 67 | .ant-empty-img-simple-path { 68 | fill: #fafafa; 69 | } 70 | .ant-empty-rtl { 71 | direction: rtl; 72 | } 73 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // 有关 tasks.json 格式的文档,请参见 3 | // https://go.microsoft.com/fwlink/?LinkId=733558 4 | "version": "2.0.0", 5 | "tasks": [ 6 | //f4 7 | { 8 | "type": "shell", 9 | "command": "git pull gitlab master", 10 | "label": "git pull", 11 | "problemMatcher": [] 12 | }, 13 | //f6 14 | { 15 | "type": "shell", 16 | "command": "git push", 17 | "label": "git push", 18 | "problemMatcher": [] 19 | }, 20 | //f8 start 21 | { 22 | "type": "shell", 23 | "command": "cd doc && npm start", 24 | "label": "start", 25 | "problemMatcher": [] 26 | }, 27 | //f9 build 28 | { 29 | "type": "shell", 30 | "command": "npm run build && npm publish", 31 | "label": "build", 32 | "problemMatcher": [] 33 | }, 34 | //f10 publish 35 | { 36 | "type": "shell", 37 | "command": "npm publish", 38 | "label": "publish", 39 | "problemMatcher": [] 40 | }, 41 | //f11 my install 42 | { 43 | "type": "shell", 44 | "command": "cd doc && cnpm i", 45 | "label": "my install", 46 | "problemMatcher": [] 47 | }, 48 | //f12 reset 49 | { 50 | "type": "shell", 51 | "command": "cd doc && rm -rf node_modules", 52 | "label": "reset", 53 | "problemMatcher": [] 54 | }, 55 | { 56 | "type": "shell", 57 | "command": "git checkout master && git merge feature-0-dev && git add . && git commit -m 'merge' && git push", 58 | "label": "merge", 59 | "problemMatcher": [] 60 | } 61 | 62 | 63 | ] 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /doc/src/.components/Background.tsx: -------------------------------------------------------------------------------- 1 | 2 | export default () => { 3 | function randomNum(minNum:number, maxNum:number) { 4 | switch (arguments.length) { 5 | case 1: 6 | return Math.floor(Math.random() * minNum + 1); 7 | break; 8 | case 2: 9 | return Math.floor(Math.random() * (maxNum - minNum + 1) + minNum); 10 | break; 11 | default: 12 | return 0; 13 | break; 14 | } 15 | } 16 | 17 | const getPosition = () => { 18 | const fontSize = randomNum(40,90) 19 | const top = randomNum(0,100)+'%' 20 | const left = randomNum(0,100)+'%' 21 | return {fontSize,top,left}; 22 | }; 23 | 24 | return ( 25 |
26 | 27 |
28 | ○ 29 |
30 |
31 | + 32 |
33 |
34 | - 35 |
36 |
37 | ◇ 38 |
39 |
40 | △ 41 |
42 |
43 | ⊙ 44 |
45 |
46 | Win 47 |
48 |
49 | Commond 50 |
51 |
52 | CTRL 53 |
54 |
55 | ALT 56 |
57 |
58 | SHIFT 59 |
60 |
61 | ); 62 | }; 63 | -------------------------------------------------------------------------------- /doc/src/components/Background.tsx: -------------------------------------------------------------------------------- 1 | 2 | export default () => { 3 | function randomNum(minNum:number, maxNum:number) { 4 | switch (arguments.length) { 5 | case 1: 6 | return Math.floor(Math.random() * minNum + 1); 7 | break; 8 | case 2: 9 | return Math.floor(Math.random() * (maxNum - minNum + 1) + minNum); 10 | break; 11 | default: 12 | return 0; 13 | break; 14 | } 15 | } 16 | 17 | const getPosition = () => { 18 | const fontSize = randomNum(40,90) 19 | const top = randomNum(0,100)+'%' 20 | const left = randomNum(0,100)+'%' 21 | return {fontSize,top,left}; 22 | }; 23 | 24 | return ( 25 |
26 | 27 |
28 | ○ 29 |
30 |
31 | + 32 |
33 |
34 | - 35 |
36 |
37 | ◇ 38 |
39 |
40 | △ 41 |
42 |
43 | ⊙ 44 |
45 |
46 | Win 47 |
48 |
49 | Commond 50 |
51 |
52 | CTRL 53 |
54 |
55 | ALT 56 |
57 |
58 | SHIFT 59 |
60 |
61 | ); 62 | }; 63 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/utils.tsx: -------------------------------------------------------------------------------- 1 | // import { updateApi as modifySmartChartConfig } from '@/pages/common/widgets/smartchart/service' 2 | import _ from 'lodash'; 3 | 4 | export const request = async (url: string, options: any) => { 5 | const { 6 | method, 7 | data: { dataId, dataType, bigData }, 8 | } = options; 9 | let res; 10 | 11 | switch (method) { 12 | case 'POST': 13 | localStorage.setItem(`${dataId}-${dataType}`, bigData); 14 | break; 15 | case 'GET': 16 | res = localStorage.getItem(`${dataId}-${dataType}`); 17 | break; 18 | case 'DELETE': 19 | localStorage.removeItem(`${dataId}-${dataType}`); 20 | } 21 | 22 | res = localStorage.getItem(`${dataId}-${dataType}`); 23 | 24 | return res; 25 | }; 26 | 27 | /** 28 | *复制字符串到系统剪切板 29 | * 30 | * @param {*} str 31 | */ 32 | export const copy = (str: string) => { 33 | var save = function (e: any) { 34 | e.clipboardData.setData('text/plain', str); 35 | e.preventDefault(); //阻止默认行为 36 | }; 37 | document.addEventListener('copy', save); 38 | document.execCommand('copy'); 39 | setTimeout(() => { 40 | document.removeEventListener('copy', save); 41 | }, 1000); 42 | }; 43 | 44 | export const formatLayout = (layout) => { 45 | const data = _.cloneDeep(layout); 46 | data.forEach((item) => { 47 | delete item.minW; 48 | delete item.maxW; 49 | delete item.minH; 50 | delete item.maxH; 51 | delete item.moved; 52 | delete item.static; 53 | }); 54 | return data; 55 | }; 56 | 57 | //添加最大最小值 58 | export const calcMinAndMax = (data, widgets) => { 59 | data.map((item, index) => { 60 | const key = item.i.split('-')[0]; 61 | if (!key) { 62 | return; 63 | } 64 | const { minW = 1, maxW = 12, minH = 1, maxH = 100 } = widgets[key]; 65 | item.minW = minW; 66 | item.maxW = maxW; 67 | item.minH = minH; 68 | item.maxH = maxH; 69 | }); 70 | return data; 71 | }; 72 | -------------------------------------------------------------------------------- /demo/.umi/umi.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import './core/polyfill'; 3 | import '@@/core/devScripts'; 4 | import { plugin } from './core/plugin'; 5 | import './core/pluginRegister'; 6 | import { createHistory } from './core/history'; 7 | import { ApplyPluginsType } from '/Users/yuanguandong/Desktop/github/react-dashboard-pro/node_modules/.pnpm/@umijs+runtime@3.5.20_react@16.14.0/node_modules/@umijs/runtime'; 8 | import { renderClient } from '/Users/yuanguandong/Desktop/github/react-dashboard-pro/node_modules/.pnpm/@umijs+renderer-react@3.5.20_39566ec7cc5fe716a59f91f7330320ef/node_modules/@umijs/renderer-react'; 9 | import { getRoutes } from './core/routes'; 10 | 11 | 12 | 13 | 14 | const getClientRender = (args: { hot?: boolean; routes?: any[] } = {}) => plugin.applyPlugins({ 15 | key: 'render', 16 | type: ApplyPluginsType.compose, 17 | initialValue: () => { 18 | const opts = plugin.applyPlugins({ 19 | key: 'modifyClientRenderOpts', 20 | type: ApplyPluginsType.modify, 21 | initialValue: { 22 | routes: args.routes || getRoutes(), 23 | plugin, 24 | history: createHistory(args.hot), 25 | isServer: process.env.__IS_SERVER, 26 | rootElement: 'root', 27 | defaultTitle: ``, 28 | }, 29 | }); 30 | return renderClient(opts); 31 | }, 32 | args, 33 | }); 34 | 35 | const clientRender = getClientRender(); 36 | export default clientRender(); 37 | 38 | 39 | window.g_umi = { 40 | version: '3.5.20', 41 | }; 42 | 43 | 44 | // hot module replacement 45 | // @ts-ignore 46 | if (module.hot) { 47 | // @ts-ignore 48 | module.hot.accept('./core/routes', () => { 49 | const ret = require('./core/routes'); 50 | if (ret.then) { 51 | ret.then(({ getRoutes }) => { 52 | getClientRender({ hot: true, routes: getRoutes() })(); 53 | }); 54 | } else { 55 | getClientRender({ hot: true, routes: ret.getRoutes() })(); 56 | } 57 | }); 58 | } 59 | -------------------------------------------------------------------------------- /doc/src/.components/api/Layout.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from 'antd'; 2 | 3 | export default (props:any)=>{ 4 | 5 | const dataSource = [ 6 | { 7 | prop: `i`, 8 | desc: `唯一标识, 以小程序的唯一标识加中划线开头,如 'widgetKey-1234567'`, 9 | type: `string`, 10 | default: ``, 11 | required: `true` 12 | },{ 13 | prop: `w`, 14 | desc: `宽度份数,总共12份`, 15 | type: `number`, 16 | default: ``, 17 | required: `true` 18 | }, 19 | { 20 | prop: `h`, 21 | desc: `高度份数,1份大概30px`, 22 | type: `number`, 23 | default: ``, 24 | required: `true` 25 | },{ 26 | prop: `x`, 27 | desc: `横向位置,总共12份`, 28 | type: `number`, 29 | default: ``, 30 | required: `true` 31 | },{ 32 | prop: `y`, 33 | desc: `纵向位置,1份大概30px`, 34 | type: `number`, 35 | default: ``, 36 | required: `true` 37 | },{ 38 | prop: `minW`, 39 | desc: `最小宽度`, 40 | type: `number`, 41 | default: ``, 42 | required: `true` 43 | },{ 44 | prop: `maxW`, 45 | desc: `最大宽度`, 46 | type: `number`, 47 | default: ``, 48 | required: `true` 49 | },{ 50 | prop: `minH`, 51 | desc: `最小高度`, 52 | type: `number`, 53 | default: ``, 54 | required: `true` 55 | },{ 56 | prop: `maxH`, 57 | desc: `最大高度`, 58 | type: `number`, 59 | default: ``, 60 | required: `true` 61 | } 62 | ]; 63 | 64 | const columns = [ 65 | { 66 | title: '属性', 67 | dataIndex: 'prop', 68 | key: 'prop', 69 | }, 70 | { 71 | title: '说明', 72 | dataIndex: 'desc', 73 | key: 'desc', 74 | }, 75 | { 76 | title: '类型', 77 | dataIndex: 'type', 78 | key: 'type', 79 | }, 80 | { 81 | title: '默认值', 82 | dataIndex: 'default', 83 | key: 'default', 84 | }, 85 | { 86 | title: '是否必传', 87 | dataIndex: 'required', 88 | key: 'required', 89 | }, 90 | ]; 91 | 92 | return 93 | } -------------------------------------------------------------------------------- /doc/src/components/api/Layout.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from 'antd'; 2 | 3 | export default (props:any)=>{ 4 | 5 | const dataSource = [ 6 | { 7 | prop: `i`, 8 | desc: `唯一标识, 以小程序的key-uuid组成,加中划线分割,如 'Todo-53084247679600442035440807237732',uuid不限制位数,只需确保当前仪表板中唯一即可`, 9 | type: `string`, 10 | default: ``, 11 | required: `true` 12 | },{ 13 | prop: `w`, 14 | desc: `宽度份数,总共12份`, 15 | type: `number`, 16 | default: ``, 17 | required: `true` 18 | }, 19 | { 20 | prop: `h`, 21 | desc: `高度份数,1份大概30px`, 22 | type: `number`, 23 | default: ``, 24 | required: `true` 25 | },{ 26 | prop: `x`, 27 | desc: `横向位置,总共12份`, 28 | type: `number`, 29 | default: ``, 30 | required: `true` 31 | },{ 32 | prop: `y`, 33 | desc: `纵向位置,1份大概30px`, 34 | type: `number`, 35 | default: ``, 36 | required: `true` 37 | },{ 38 | prop: `minW`, 39 | desc: `最小宽度`, 40 | type: `number`, 41 | default: ``, 42 | required: `true` 43 | },{ 44 | prop: `maxW`, 45 | desc: `最大宽度`, 46 | type: `number`, 47 | default: ``, 48 | required: `true` 49 | },{ 50 | prop: `minH`, 51 | desc: `最小高度`, 52 | type: `number`, 53 | default: ``, 54 | required: `true` 55 | },{ 56 | prop: `maxH`, 57 | desc: `最大高度`, 58 | type: `number`, 59 | default: ``, 60 | required: `true` 61 | } 62 | ]; 63 | 64 | const columns = [ 65 | { 66 | title: '属性', 67 | dataIndex: 'prop', 68 | key: 'prop', 69 | }, 70 | { 71 | title: '说明', 72 | dataIndex: 'desc', 73 | key: 'desc', 74 | }, 75 | { 76 | title: '类型', 77 | dataIndex: 'type', 78 | key: 'type', 79 | }, 80 | { 81 | title: '默认值', 82 | dataIndex: 'default', 83 | key: 'default', 84 | }, 85 | { 86 | title: '是否必传', 87 | dataIndex: 'required', 88 | key: 'required', 89 | }, 90 | ]; 91 | 92 | return
93 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-dashboard-pro", 3 | "version": "1.0.22", 4 | "description": "Out of the box one-stop dashboard solution 开箱即用的一站式仪表板解决方案", 5 | "keywords": [ 6 | "dashboard", 7 | "react", 8 | "javascript", 9 | "tsx", 10 | "antd", 11 | "react-dashboard-pro", 12 | "仪表板" 13 | ], 14 | "homepage": "https://yuanguandong.github.io/react-dashboard-pro/", 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/yuanguandong/react-dashboard-pro" 18 | }, 19 | "author": "yuanguandong", 20 | "license": "MIT", 21 | "main": "lib/index.js", 22 | "module": "lib/index.esm.js", 23 | "scripts": { 24 | "start": "cd doc && npm i && npm start", 25 | "dev": "set NODE_ENV=developemnt&& rollup -c rollup.config.js -w", 26 | "build": "rm -rf lib && set NODE_ENV=production && rollup -c rollup.config.js" 27 | }, 28 | "types": "lib/index.d.ts", 29 | "devDependencies": { 30 | "@babel/core": "^7.15.0", 31 | "@emotion/react": "^11.4.1", 32 | "@emotion/styled": "^11.3.0", 33 | "@types/lodash": "^4.14.172", 34 | "@types/react": "^17.0.13", 35 | "@types/react-grid-layout": "^1.1.2", 36 | "@typescript-eslint/parser": "^4.28.2", 37 | "classnames": "^2.3.1", 38 | "postcss": "^8.3.6", 39 | "react": "^17.0.2", 40 | "react-dom": "^17.0.2", 41 | "react-resize-detector": "^6.7.6", 42 | "rollup-plugin-babel": "^4.4.0", 43 | "rollup-plugin-commonjs": "^10.1.0", 44 | "rollup-plugin-eslint": "^7.0.0", 45 | "rollup-plugin-less": "^1.1.3", 46 | "rollup-plugin-node-resolve": "^5.2.0", 47 | "rollup-plugin-postcss": "^4.0.1", 48 | "rollup-plugin-typescript2": "^0.30.0", 49 | "rollup-plugin-uglify": "^6.0.4", 50 | "tslib": "^2.3.0", 51 | "typescript": "^4.3.5" 52 | }, 53 | "files": [ 54 | "lib" 55 | ], 56 | "dependencies": { 57 | "@ant-design/charts": "^1.2.10", 58 | "@ant-design/icons": "^4.6.3", 59 | "antd": "^4.16.13", 60 | "lodash": "^4.17.21", 61 | "react-grid-layout": "^1.2.5", 62 | "react-icons": "^4.2.0", 63 | "react-keyevent": "^1.0.9", 64 | "react-resizable": "^3.0.4", 65 | "react-resize-detector": "^6.7.6", 66 | "rollup": "^2.66.1", 67 | "umi": "^3.5.20" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/style/message.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */ 2 | /* stylelint-disable no-duplicate-selectors */ 3 | /* stylelint-disable */ 4 | /* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */ 5 | .ant-message { 6 | box-sizing: border-box; 7 | margin: 0; 8 | padding: 0; 9 | color: rgba(0, 0, 0, 0.85); 10 | font-size: 14px; 11 | font-variant: tabular-nums; 12 | line-height: 1.5715; 13 | list-style: none; 14 | font-feature-settings: 'tnum'; 15 | position: fixed; 16 | top: 8px; 17 | left: 0; 18 | z-index: 1010; 19 | width: 100%; 20 | pointer-events: none; 21 | } 22 | .ant-message-notice { 23 | padding: 8px; 24 | text-align: center; 25 | } 26 | .ant-message-notice-content { 27 | display: inline-block; 28 | padding: 10px 16px; 29 | background: #fff; 30 | border-radius: 2px; 31 | box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05); 32 | pointer-events: all; 33 | } 34 | .ant-message-success .anticon { 35 | color: #52c41a; 36 | } 37 | .ant-message-error .anticon { 38 | color: #ff4d4f; 39 | } 40 | .ant-message-warning .anticon { 41 | color: #faad14; 42 | } 43 | .ant-message-info .anticon, 44 | .ant-message-loading .anticon { 45 | color: #1890ff; 46 | } 47 | .ant-message .anticon { 48 | position: relative; 49 | top: 1px; 50 | margin-right: 8px; 51 | font-size: 16px; 52 | } 53 | .ant-message-notice.ant-move-up-leave.ant-move-up-leave-active { 54 | -webkit-animation-name: MessageMoveOut; 55 | animation-name: MessageMoveOut; 56 | -webkit-animation-duration: 0.3s; 57 | animation-duration: 0.3s; 58 | } 59 | @-webkit-keyframes MessageMoveOut { 60 | 0% { 61 | max-height: 150px; 62 | padding: 8px; 63 | opacity: 1; 64 | } 65 | 100% { 66 | max-height: 0; 67 | padding: 0; 68 | opacity: 0; 69 | } 70 | } 71 | @keyframes MessageMoveOut { 72 | 0% { 73 | max-height: 150px; 74 | padding: 8px; 75 | opacity: 1; 76 | } 77 | 100% { 78 | max-height: 0; 79 | padding: 0; 80 | opacity: 0; 81 | } 82 | } 83 | .ant-message-rtl { 84 | direction: rtl; 85 | } 86 | .ant-message-rtl span { 87 | direction: rtl; 88 | } 89 | .ant-message-rtl .anticon { 90 | margin-right: 0; 91 | margin-left: 8px; 92 | } 93 | -------------------------------------------------------------------------------- /doc/src/components/api/Ref.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from 'antd'; 2 | 3 | // dom: dom.current, 4 | // reset, //清空 5 | // removeWidget, //删除 6 | // addWidget, //新增 7 | // reload, // 刷新 8 | // cancelEdit, //取消编辑 9 | // edit, //编辑 10 | // revert, //重置 11 | // save, //保存 12 | 13 | 14 | export default (props:any)=>{ 15 | 16 | const dataSource = [ 17 | { 18 | prop: `dom`, 19 | desc: `DOM对象`, 20 | type: `HTMLDivElement`, 21 | default: ``, 22 | required: `false` 23 | } 24 | ,{ 25 | prop: `addWidget`, 26 | desc: `添加小程序`, 27 | type: <>(widget{`)=>void`}, 28 | default: ``, 29 | required: `false` 30 | }, 31 | { 32 | prop: `removeWidget`, 33 | desc: `删除小程序`, 34 | type: <>(i:widgetKey{`)=>void`}, 35 | default: ``, 36 | required: `false` 37 | },{ 38 | prop: `reload`, 39 | desc: `刷新`, 40 | type: `()=>void`, 41 | default: ``, 42 | required: `false` 43 | },{ 44 | prop: `edit`, 45 | desc: `进入编辑`, 46 | type: `()=>void`, 47 | default: ``, 48 | required: `false` 49 | },{ 50 | prop: `cancelEdit`, 51 | desc: `取消编辑`, 52 | type: `()=>void`, 53 | default: ``, 54 | required: `false` 55 | },{ 56 | prop: `reset`, 57 | desc: `清空布局`, 58 | type: `()=>void`, 59 | default: ``, 60 | required: `false` 61 | },{ 62 | prop: `revert`, 63 | desc: `重置`, 64 | type: `()=>void`, 65 | default: ``, 66 | required: `false` 67 | },{ 68 | prop: `save`, 69 | desc: `保存`, 70 | type: `()=>void`, 71 | default: ``, 72 | required: `false` 73 | } 74 | ]; 75 | 76 | const columns = [ 77 | { 78 | title: '属性', 79 | dataIndex: 'prop', 80 | key: 'prop', 81 | }, 82 | { 83 | title: '说明', 84 | dataIndex: 'desc', 85 | key: 'desc', 86 | }, 87 | { 88 | title: '类型', 89 | dataIndex: 'type', 90 | key: 'type', 91 | }, 92 | // { 93 | // title: '默认值', 94 | // dataIndex: 'default', 95 | // key: 'default', 96 | // }, 97 | // { 98 | // title: '是否必传', 99 | // dataIndex: 'required', 100 | // key: 'required', 101 | // }, 102 | ]; 103 | 104 | return
105 | } -------------------------------------------------------------------------------- /demo/src/widgets/popular/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Popular'; 2 | @speed:0.5s; 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | // user-select: none; 7 | 8 | padding: 10px; 9 | background: var(--component-background); 10 | 11 | overflow-y: auto; 12 | &::-webkit-scrollbar { 13 | width: 1px; 14 | height: 1px; 15 | overflow: auto; 16 | } 17 | 18 | &::-webkit-scrollbar-thumb { 19 | background-color: var(--primary-color); 20 | min-height: 25px; 21 | min-width: 25px; 22 | 23 | &:hover { 24 | background-color: #a8a8a8; 25 | } 26 | 27 | &:active { 28 | background-color: #787878; 29 | } 30 | } 31 | 32 | &::-webkit-scrollbar-track { 33 | background-color: #f7f7f7; 34 | border: 1px solid #efefef; 35 | } 36 | 37 | &-hero { 38 | width: 100%; 39 | height: 200px; 40 | background-size: cover; 41 | background-position: center center; 42 | transition: all @speed; 43 | 44 | } 45 | &-list { 46 | width: 100%; 47 | .@{widgetClassName}-item { 48 | cursor: pointer; 49 | transition: all @speed; 50 | overflow:hidden; 51 | margin-bottom:10px; 52 | width: 100%; 53 | display: flex; 54 | .@{widgetClassName}-img { 55 | width: 100px; 56 | transition: all @speed; 57 | height: 60px; 58 | border-radius: 10px; 59 | background-size: cover; 60 | background-position: center center; 61 | } 62 | .@{widgetClassName}-content { 63 | transition: all @speed; 64 | padding: 5px 10px; 65 | flex: 1; 66 | .@{widgetClassName}-title { 67 | display: flex; 68 | .@{widgetClassName}-left { 69 | transition: all @speed; 70 | flex: 1; 71 | font-size: 16px; 72 | font-weight: bold; 73 | } 74 | .@{widgetClassName}-right { 75 | } 76 | } 77 | .@{widgetClassName}-desc { 78 | display: flex; 79 | .@{widgetClassName}-left { 80 | transition: all @speed; 81 | flex: 1; 82 | color: rgba(128, 128, 128, 0.5); 83 | } 84 | .@{widgetClassName}-right { 85 | color: rgba(128, 128, 128, 0.5); 86 | } 87 | } 88 | } 89 | } 90 | } 91 | &-body{ 92 | transition: all @speed; 93 | } 94 | &-close{ 95 | width:100%; 96 | padding:30px; 97 | text-align:center; 98 | font-size:24px; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /doc/src/widgets/popular/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Popular'; 2 | @speed:0.5s; 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | // user-select: none; 7 | 8 | padding: 10px; 9 | background: var(--component-background); 10 | 11 | overflow-y: auto; 12 | &::-webkit-scrollbar { 13 | width: 1px; 14 | height: 1px; 15 | overflow: auto; 16 | } 17 | 18 | &::-webkit-scrollbar-thumb { 19 | background-color: var(--primary-color); 20 | min-height: 25px; 21 | min-width: 25px; 22 | 23 | &:hover { 24 | background-color: #a8a8a8; 25 | } 26 | 27 | &:active { 28 | background-color: #787878; 29 | } 30 | } 31 | 32 | &::-webkit-scrollbar-track { 33 | background-color: #f7f7f7; 34 | border: 1px solid #efefef; 35 | } 36 | 37 | &-hero { 38 | width: 100%; 39 | height: 200px; 40 | background-size: cover; 41 | background-position: center center; 42 | transition: all @speed; 43 | 44 | } 45 | &-list { 46 | width: 100%; 47 | .@{widgetClassName}-item { 48 | cursor: pointer; 49 | transition: all @speed; 50 | overflow:hidden; 51 | margin-bottom:10px; 52 | width: 100%; 53 | display: flex; 54 | .@{widgetClassName}-img { 55 | width: 100px; 56 | transition: all @speed; 57 | height: 60px; 58 | border-radius: 10px; 59 | background-size: cover; 60 | background-position: center center; 61 | } 62 | .@{widgetClassName}-content { 63 | transition: all @speed; 64 | padding: 5px 10px; 65 | flex: 1; 66 | .@{widgetClassName}-title { 67 | display: flex; 68 | .@{widgetClassName}-left { 69 | transition: all @speed; 70 | flex: 1; 71 | font-size: 16px; 72 | font-weight: bold; 73 | } 74 | .@{widgetClassName}-right { 75 | } 76 | } 77 | .@{widgetClassName}-desc { 78 | display: flex; 79 | .@{widgetClassName}-left { 80 | transition: all @speed; 81 | flex: 1; 82 | color: rgba(128, 128, 128, 0.5); 83 | } 84 | .@{widgetClassName}-right { 85 | color: rgba(128, 128, 128, 0.5); 86 | } 87 | } 88 | } 89 | } 90 | } 91 | &-body{ 92 | transition: all @speed; 93 | } 94 | &-close{ 95 | width:100%; 96 | padding:30px; 97 | text-align:center; 98 | font-size:24px; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /doc/src/.components/api/Widget.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from 'antd'; 2 | 3 | export default (props:any)=>{ 4 | 5 | const dataSource = [ 6 | { 7 | prop: `name`, 8 | desc: `小程序名称`, 9 | type: `string`, 10 | default: ``, 11 | required: `true` 12 | }, 13 | { 14 | prop: `description`, 15 | desc: `小程序描述`, 16 | type: `string`, 17 | default: ``, 18 | required: `true` 19 | },{ 20 | prop: `tags`, 21 | desc: `标签,被用作小程序选择器分类依据`, 22 | type: `string[]`, 23 | default: ``, 24 | required: `true` 25 | },{ 26 | prop: `component`, 27 | desc: `小程序组件`, 28 | type: `ReactElement`, 29 | default: ``, 30 | required: `true` 31 | },{ 32 | prop: `configComponent`, 33 | desc: `小程序对应的配置组件`, 34 | type: `ReactElement`, 35 | default: ``, 36 | required: `true` 37 | },{ 38 | prop: `maxLength`, 39 | desc: `该小程序在当前仪表板最大可添加数量`, 40 | type: `number`, 41 | default: ``, 42 | required: `true` 43 | },{ 44 | prop: `snapShot`, 45 | desc: `小程序快照图片,用于小程序选择器显示`, 46 | type: `ImageBitmapSource`, 47 | default: ``, 48 | required: `true` 49 | },{ 50 | prop: `icon`, 51 | desc: `小程序图标,用于小程序选择器显示`, 52 | type: `ReactElement`, 53 | default: ``, 54 | required: `true` 55 | },{ 56 | prop: `iconBackground`, 57 | desc: `小程序图标背景,用于小程序选择器显示`, 58 | type: `string`, 59 | default: ``, 60 | required: `true` 61 | },{ 62 | prop: `size`, 63 | desc: `小程序尺寸信息`, 64 | type: `{ 65 | defaultWidth: number; 66 | defaultHeight: number; 67 | maxWidth: number; 68 | maxHeight: number; 69 | minWidth: number; 70 | minHeight: number; 71 | }`, 72 | default: ``, 73 | required: `true` 74 | } 75 | ]; 76 | 77 | const columns = [ 78 | { 79 | title: '属性', 80 | dataIndex: 'prop', 81 | key: 'prop', 82 | }, 83 | { 84 | title: '说明', 85 | dataIndex: 'desc', 86 | key: 'desc', 87 | }, 88 | { 89 | title: '类型', 90 | dataIndex: 'type', 91 | key: 'type', 92 | }, 93 | { 94 | title: '默认值', 95 | dataIndex: 'default', 96 | key: 'default', 97 | }, 98 | { 99 | title: '是否必传', 100 | dataIndex: 'required', 101 | key: 'required', 102 | }, 103 | ]; 104 | 105 | return
106 | } -------------------------------------------------------------------------------- /doc/src/components/api/Widget.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from 'antd'; 2 | 3 | export default (props:any)=>{ 4 | 5 | const dataSource = [ 6 | { 7 | prop: `name`, 8 | desc: `小程序名称`, 9 | type: `string`, 10 | default: ``, 11 | required: `true` 12 | }, 13 | { 14 | prop: `description`, 15 | desc: `小程序描述`, 16 | type: `string`, 17 | default: ``, 18 | required: `true` 19 | },{ 20 | prop: `tags`, 21 | desc: `标签,被用作小程序选择器分类依据`, 22 | type: `string[]`, 23 | default: ``, 24 | required: `true` 25 | },{ 26 | prop: `component`, 27 | desc: `小程序组件`, 28 | type: `Component | FunctionComponent`, 29 | default: ``, 30 | required: `true` 31 | },{ 32 | prop: `configComponent`, 33 | desc: `小程序对应的配置组件`, 34 | type: `Component | FunctionComponent | null`, 35 | default: ``, 36 | required: `true` 37 | },{ 38 | prop: `maxLength`, 39 | desc: `该小程序在当前仪表板最大可添加数量`, 40 | type: `number`, 41 | default: ``, 42 | required: `true` 43 | },{ 44 | prop: `snapShot`, 45 | desc: `小程序快照图片,用于小程序选择器显示`, 46 | type: `ImageBitmapSource`, 47 | default: ``, 48 | required: `true` 49 | },{ 50 | prop: `icon`, 51 | desc: `小程序图标,用于小程序选择器显示`, 52 | type: `ReactElement`, 53 | default: ``, 54 | required: `true` 55 | },{ 56 | prop: `iconBackground`, 57 | desc: `小程序图标背景,用于小程序选择器显示`, 58 | type: `string`, 59 | default: ``, 60 | required: `true` 61 | },{ 62 | prop: `size`, 63 | desc: `小程序尺寸信息`, 64 | type: `{ 65 | defaultWidth: number; 66 | defaultHeight: number; 67 | maxWidth: number; 68 | maxHeight: number; 69 | minWidth: number; 70 | minHeight: number; 71 | }`, 72 | default: ``, 73 | required: `true` 74 | } 75 | ]; 76 | 77 | const columns = [ 78 | { 79 | title: '属性', 80 | dataIndex: 'prop', 81 | key: 'prop', 82 | }, 83 | { 84 | title: '说明', 85 | dataIndex: 'desc', 86 | key: 'desc', 87 | }, 88 | { 89 | title: '类型', 90 | dataIndex: 'type', 91 | key: 'type', 92 | }, 93 | { 94 | title: '默认值', 95 | dataIndex: 'default', 96 | key: 'default', 97 | }, 98 | { 99 | title: '是否必传', 100 | dataIndex: 'required', 101 | key: 'required', 102 | }, 103 | ]; 104 | 105 | return
106 | } -------------------------------------------------------------------------------- /doc/src/package/utils.tsx: -------------------------------------------------------------------------------- 1 | import { Modal } from 'antd'; 2 | import { ReactNode } from 'react'; 3 | 4 | export function randomNum(minNum: number, maxNum: number) { 5 | switch (arguments.length) { 6 | case 1: 7 | return Math.floor(Math.random() * minNum + 1); 8 | break; 9 | case 2: 10 | return Math.floor(Math.random() * (maxNum - minNum + 1) + minNum); 11 | break; 12 | default: 13 | return 0; 14 | break; 15 | } 16 | } 17 | 18 | export const getPosition = (random: any, fontSize: number) => { 19 | if (!random) { 20 | return { 21 | fontSize, 22 | }; 23 | } 24 | const { fontSizeRange } = random; 25 | const [minNum, maxNum] = fontSizeRange; 26 | const fontSizeFin = randomNum(minNum, maxNum); 27 | const top = randomNum(0, 100) + '%'; 28 | const left = randomNum(0, 100) + '%'; 29 | return { fontSize: fontSizeFin, top, left }; 30 | }; 31 | 32 | /* 33 | 生成uuid 34 | len:number 长度 35 | radix:number 进制 36 | */ 37 | export function generateUuid(len: number = 32, radix: number = 10): string { 38 | const chars = 39 | '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); 40 | const uuid = []; 41 | let i; 42 | radix = radix || chars.length; 43 | 44 | if (len) { 45 | // Compact form 46 | for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]; 47 | } else { 48 | // rfc4122, version 4 form 49 | let r; 50 | 51 | // rfc4122 requires these characters 52 | uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; 53 | uuid[14] = '4'; 54 | 55 | // Fill in random data. At i==19 set the high bits of clock sequence as 56 | // per rfc4122, sec. 4.1.5 57 | for (i = 0; i < 36; i++) { 58 | if (!uuid[i]) { 59 | r = 0 | (Math.random() * 16); 60 | uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]; 61 | } 62 | } 63 | } 64 | 65 | return uuid.join(''); 66 | } 67 | 68 | interface confirmUtilAsyncProps { 69 | content: string | ReactNode; //提示内容 70 | [key: string]: any; 71 | } 72 | const { confirm } = Modal; 73 | /** 74 | * 异步确认弹窗,抛出确认或取消布尔值 75 | * 76 | * @param {confirmUtilAsyncProps} props 77 | */ 78 | export const confirmUtilAsync = (props: confirmUtilAsyncProps) => 79 | new Promise((resolve, reject) => { 80 | const { content, okType = 'primary', ...restProps } = props; 81 | confirm({ 82 | title: '提示', 83 | content, 84 | cancelText: '取消', 85 | okText: '确定', 86 | okType, 87 | okButtonProps: { 88 | size: 'small', 89 | }, 90 | zIndex: 9999, 91 | cancelButtonProps: { 92 | size: 'small', 93 | }, 94 | onOk() { 95 | resolve(true); 96 | }, 97 | onCancel() { 98 | resolve(false); 99 | }, 100 | ...restProps, 101 | }); 102 | }); 103 | 104 | // 基础reducer 105 | export function reducer(state: any, action: any) { 106 | switch (action.type) { 107 | case 'save': 108 | return { 109 | ...state, 110 | ...action.payload, 111 | }; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /doc/src/widgets/clock/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Clock'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | &-left { 8 | position: relative; 9 | background: var(--primary-color); 10 | } 11 | 12 | &-right { 13 | position: relative; 14 | display: flex; 15 | flex-direction: column; 16 | background: var(--component-background); 17 | } 18 | 19 | &-calender { 20 | padding: 0 20px; 21 | display: flex; 22 | width: 100%; 23 | height: 40px; 24 | line-height: 40px; 25 | border-top: 1px solid rgba(0, 0, 0, 0.05); 26 | } 27 | 28 | &-timeNum { 29 | font-family: 'UnidreamLED'; 30 | text-align: center; 31 | display: block; 32 | width: 100%; 33 | flex: 1; 34 | display: flex; 35 | justify-content: center; 36 | align-items: center; 37 | } 38 | 39 | &-day { 40 | font-size: 14px; 41 | font-weight: bold; 42 | text-align: right; 43 | flex: 1; 44 | } 45 | 46 | &-year { 47 | font-size: 14px; 48 | text-align: left; 49 | font-weight: bold; 50 | } 51 | 52 | &-clock { 53 | position: absolute; 54 | top: 50%; 55 | left: 50%; 56 | margin: 0 auto; 57 | width: 80px; 58 | height: 80px; 59 | border-radius: 500px; 60 | -webkit-transform: translate(-50%, -50%); 61 | transform: translate(-50%, -50%); 62 | -ms-transform: translate(-50%, -50%); 63 | background: var(--primary-color); 64 | } 65 | 66 | &-c1 { 67 | position: absolute; 68 | width: 80px; 69 | height: 80px; 70 | } 71 | 72 | &-c2 { 73 | position: relative; 74 | margin: 5px auto 0; 75 | width: 70px; 76 | height: 70px; 77 | border: 5px solid #fff; 78 | border-radius: 100%; 79 | box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5); 80 | } 81 | 82 | &-pin { 83 | position: absolute; 84 | z-index: 4; 85 | margin: 22.5px 0 0 22.5px; 86 | width: 15px; 87 | height: 15px; 88 | border: 5px solid #fff; 89 | border-radius: 100%; 90 | box-shadow: 0 0px 5px rgba(0, 0, 0, 0.5); 91 | } 92 | 93 | &-clockInner { 94 | position: relative; 95 | margin: 0 auto 0; 96 | width: 5px; 97 | height: 5px; 98 | border-radius: 100%; 99 | background: var(--primary-color); 100 | } 101 | 102 | &-hr, 103 | &-min, 104 | &-sec { 105 | position: absolute; 106 | -webkit-transform: rotate(0); 107 | transform: rotate(0); 108 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.8); 109 | } 110 | 111 | &-sec { 112 | z-index: 3; 113 | margin: 0; 114 | margin: 30px 0 0 31px; 115 | width: 1px; 116 | height: 28px; 117 | border-radius: 4px; 118 | background: #fff; 119 | transform-origin: 0 0; 120 | } 121 | 122 | &-min { 123 | z-index: 2; 124 | margin: 7px 0 0 28px; 125 | width: 4px; 126 | height: 25px; 127 | border-radius: 30px; 128 | background: #fff; 129 | transform-origin: 2px 23px; 130 | } 131 | 132 | &-hr { 133 | z-index: 1; 134 | margin: 12px 0 0 28px; 135 | transform-origin: 2px 18px; 136 | width: 4px; 137 | height: 20px; 138 | border-radius: 30px; 139 | background: #fff; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /demo/src/widgets/clock/index.less: -------------------------------------------------------------------------------- 1 | @widgetClassName: ~'react-dashboard-widget-Clock'; 2 | 3 | .@{widgetClassName} { 4 | width: 100%; 5 | height: 100%; 6 | user-select: none; 7 | &-left { 8 | position: relative; 9 | background: var(--primary-color); 10 | } 11 | 12 | &-right { 13 | position: relative; 14 | display: flex; 15 | flex-direction: column; 16 | background: var(--component-background); 17 | } 18 | 19 | &-calender { 20 | padding: 0 20px; 21 | display: flex; 22 | width: 100%; 23 | height: 40px; 24 | line-height: 40px; 25 | border-top: 1px solid rgba(0, 0, 0, 0.05); 26 | } 27 | 28 | &-timeNum { 29 | font-family: 'UnidreamLED'; 30 | text-align: center; 31 | display: block; 32 | width: 100%; 33 | flex: 1; 34 | display: flex; 35 | justify-content: center; 36 | align-items: center; 37 | } 38 | 39 | &-day { 40 | font-size: 14px; 41 | font-weight: bold; 42 | text-align: right; 43 | flex: 1; 44 | } 45 | 46 | &-year { 47 | font-size: 14px; 48 | text-align: left; 49 | font-weight: bold; 50 | } 51 | 52 | &-clock { 53 | position: absolute; 54 | top: 50%; 55 | left: 50%; 56 | margin: 0 auto; 57 | width: 80px; 58 | height: 80px; 59 | border-radius: 500px; 60 | -webkit-transform: translate(-50%, -50%); 61 | transform: translate(-50%, -50%); 62 | -ms-transform: translate(-50%, -50%); 63 | background: var(--primary-color); 64 | } 65 | 66 | &-c1 { 67 | position: absolute; 68 | width: 80px; 69 | height: 80px; 70 | } 71 | 72 | &-c2 { 73 | position: relative; 74 | margin: 5px auto 0; 75 | width: 70px; 76 | height: 70px; 77 | border: 5px solid #fff; 78 | border-radius: 100%; 79 | box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5); 80 | } 81 | 82 | &-pin { 83 | position: absolute; 84 | z-index: 4; 85 | margin: 22.5px 0 0 22.5px; 86 | width: 15px; 87 | height: 15px; 88 | border: 5px solid #fff; 89 | border-radius: 100%; 90 | box-shadow: 0 0px 5px rgba(0, 0, 0, 0.5); 91 | } 92 | 93 | &-clockInner { 94 | position: relative; 95 | margin: 0 auto 0; 96 | width: 5px; 97 | height: 5px; 98 | border-radius: 100%; 99 | background: var(--primary-color); 100 | } 101 | 102 | &-hr, 103 | &-min, 104 | &-sec { 105 | position: absolute; 106 | -webkit-transform: rotate(0); 107 | transform: rotate(0); 108 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.8); 109 | } 110 | 111 | &-sec { 112 | z-index: 3; 113 | margin: 0; 114 | margin: 30px 0 0 31px; 115 | width: 1px; 116 | height: 28px; 117 | border-radius: 4px; 118 | background: #fff; 119 | transform-origin: 0 0; 120 | } 121 | 122 | &-min { 123 | z-index: 2; 124 | margin: 7px 0 0 28px; 125 | width: 4px; 126 | height: 25px; 127 | border-radius: 30px; 128 | background: #fff; 129 | transform-origin: 2px 23px; 130 | } 131 | 132 | &-hr { 133 | z-index: 1; 134 | margin: 12px 0 0 28px; 135 | transform-origin: 2px 18px; 136 | width: 4px; 137 | height: 20px; 138 | border-radius: 30px; 139 | background: #fff; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /doc/src/package/widget/utils.tsx: -------------------------------------------------------------------------------- 1 | import { Drawer } from 'antd'; 2 | import _ from 'lodash'; 3 | import React, { useCallback, useEffect, useMemo } from 'react'; 4 | import { AiOutlineDelete } from 'react-icons/ai'; 5 | import { FaCog } from 'react-icons/fa'; 6 | // import allWidgets from '../../widgets'; 7 | //获取widget的类型 8 | export const getWidgetType = (i: string, widgets: any): string => { 9 | let allWidgets = widgets; 10 | var widgetType = ''; 11 | Object.keys(allWidgets).map((key) => { 12 | if (i.indexOf(key) >= 0) { 13 | widgetType = key; 14 | } 15 | }); 16 | return widgetType; 17 | }; 18 | 19 | //widget配置和删除按钮 20 | export const ConfigBar = (props: any) => { 21 | const { 22 | widgetKey, 23 | editMode, 24 | onDeleteWidget, 25 | setConfigShow = () => {}, 26 | widgets 27 | } = props; 28 | const widgetType = getWidgetType(widgetKey, widgets); 29 | return ( 30 | <> 31 | {editMode &&
} 32 | {editMode && _.get('widgets', widgetType + '.configComponent') && ( 33 |
setConfigShow(true)} 36 | > 37 | 38 |
39 | )} 40 | {editMode && ( 41 |
onDeleteWidget()} 44 | > 45 | 46 |
47 | )} 48 | 49 | ); 50 | }; 51 | 52 | //config的容器 53 | export const ConfigWrap = (props: any, widgets: any) => { 54 | const { widgetKey, visible, setVisible, width, children } = props; 55 | 56 | const afterVisibleChange = useCallback( 57 | (visible) => { 58 | if (visible) { 59 | const widgetConfigPanel = 60 | document.getElementsByClassName('widgetConfigPanel')[0]; 61 | widgetConfigPanel && 62 | widgetConfigPanel.addEventListener('mousedown', function (e) { 63 | e.stopPropagation(); 64 | }); 65 | } else { 66 | const widgetConfigPanel = 67 | document.getElementsByClassName('widgetConfigPanel')[0]; 68 | widgetConfigPanel && 69 | widgetConfigPanel.removeEventListener('mousedown', function (e) { 70 | e.stopPropagation(); 71 | }); 72 | } 73 | }, 74 | [visible], 75 | ); 76 | 77 | const title = useMemo(() => { 78 | if (!widgetKey) { 79 | return; 80 | } 81 | const widgetType = getWidgetType(widgetKey, widgets); 82 | return _.get(widgets, widgetType + '.name') + '设置'; 83 | }, [widgetKey, widgets, getWidgetType]); 84 | 85 | useEffect(() => { 86 | afterVisibleChange(visible); 87 | }, [visible]); 88 | 89 | return ( 90 | <> 91 | {visible && ( 92 | setVisible(false)} 98 | visible={visible} 99 | width={width} 100 | bodyStyle={{ padding: '0px' }} 101 | afterVisibleChange={afterVisibleChange} 102 | zIndex={1005} 103 | > 104 | {children} 105 | 106 | )} 107 | 108 | ); 109 | }; 110 | -------------------------------------------------------------------------------- /doc/src/pages/index.less: -------------------------------------------------------------------------------- 1 | 2 | html,body{ 3 | background: #fff; 4 | } 5 | .App { 6 | position:relative; 7 | .wrap { 8 | width: 90%; 9 | max-width:1280px; 10 | transform: translateX(-50%); 11 | position:absolute; 12 | 13 | left:50%; 14 | margin: -350px auto; 15 | @media screen and (max-width:1200px){ 16 | min-width:90%; 17 | } 18 | } 19 | .background{ 20 | position:absolute; 21 | background:#FCD503; 22 | min-height:480px; 23 | width:100%; 24 | height:30vh; 25 | top: 0; 26 | left:0; 27 | overflow: hidden; 28 | @media screen and (max-width:1200px){ 29 | height:40vh; 30 | min-height:740px; 31 | } 32 | .symbol{ 33 | color:rgba(128,128,128,0.2); 34 | position:absolute; 35 | } 36 | 37 | } 38 | .alignCenter{text-align: center} 39 | .logo { 40 | text-align:center; 41 | font-size: 100px; 42 | font-weight: bold; 43 | line-height: 100px; 44 | user-select: none; 45 | } 46 | .name { 47 | display: inline-block; 48 | font-size: 50px; 49 | font-weight: bold; 50 | vertical-align: top; 51 | } 52 | 53 | .container { 54 | border-radius: 10px; 55 | overflow: hidden; 56 | width: 100%; 57 | // height: 350px; 58 | background:#fff; 59 | box-shadow: 5px 5px 20px rgba(0, 0, 0, 0.3); 60 | margin:20px 0; 61 | position: relative; 62 | } 63 | 64 | .block{ 65 | float: left; 66 | display: flex; 67 | justify-content: center; 68 | align-items: center; 69 | transition: all 0.3s; 70 | position: relative; 71 | &:hover { 72 | opacity: 0.9; 73 | transition: all 0.3s; 74 | } 75 | &:focus{ 76 | border:1px solid rgba(128,128,128,0.5); 77 | opacity:0.8; 78 | } 79 | &:active{ 80 | border:1px solid rgba(128,128,128,0.5); 81 | 82 | } 83 | } 84 | 85 | .TopSide { 86 | .block; 87 | background: #20252b; 88 | width: 100%; 89 | height: 50px; 90 | 91 | } 92 | 93 | .LeftSide { 94 | .block; 95 | background: #202020; 96 | height: calc(100% - 50px); 97 | 98 | } 99 | 100 | .RightSide { 101 | .block; 102 | background: #272c34; 103 | height: calc(100% - 50px); 104 | } 105 | 106 | .key { 107 | /* border:1px solid gray; */ 108 | margin: 5px; 109 | background: #fff; 110 | color: #000; 111 | padding: 3px 5px; 112 | border-radius: 3px; 113 | font-size: 12px; 114 | font-weight: bold; 115 | } 116 | 117 | .count { 118 | font-size: 14px; 119 | font-weight: bold; 120 | color: #fff; 121 | margin: 0 10px; 122 | } 123 | 124 | .tip { 125 | height: 50px; 126 | line-height: 50px; 127 | padding-left: 20px; 128 | font-size: 18px; 129 | font-weight: bold; 130 | color: #fff; 131 | position: absolute; 132 | top: 0px; 133 | left: 0px; 134 | } 135 | 136 | 137 | .code{border-radius:10px; overflow:hidden; margin:20px 0px;} 138 | 139 | pre{margin-bottom:0;padding: 30px!important;} 140 | .footer{width:100%; text-align:center; padding:50px;} 141 | .github{ 142 | position:absolute; 143 | right:20px; 144 | top:20px; 145 | width:100px; 146 | height:20px; 147 | background-repeat: no-repeat; 148 | background-position: center; 149 | width: 100px; 150 | } 151 | } 152 | 153 | 154 | -------------------------------------------------------------------------------- /demo/src/widgets/popular/component.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | CloseCircleOutlined, 3 | EllipsisOutlined, 4 | EyeOutlined 5 | } from '@ant-design/icons'; 6 | import _ from 'lodash'; 7 | import React, { useState } from 'react'; 8 | import { List } from './data'; 9 | import './index.less'; 10 | 11 | const widgetName = 'Popular'; 12 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 13 | const Widget = (props: any) => { 14 | const { height } = props; 15 | 16 | const [activeItem, setActiveItem] = useState(null); 17 | 18 | const onItemClick = (e: React.MouseEvent, item: any) => { 19 | setActiveItem(item); 20 | }; 21 | 22 | const isActive = (item: any) => { 23 | return activeItem && _.get(activeItem, 'id') === item.id; 24 | }; 25 | 26 | const onClose = (e: React.MouseEvent) => { 27 | e.stopPropagation(); 28 | e.preventDefault(); 29 | setActiveItem(null); 30 | }; 31 | 32 | 33 | return ( 34 |
35 |
45 |
46 | {List.map((item) => ( 47 |
onItemClick(e, item)} 51 | style={{ 52 | opacity: activeItem ? (isActive(item) ? 1 : 0) : 1, 53 | height: activeItem ? (isActive(item) ? 'auto' : 0) : 'auto', 54 | flexDirection: activeItem 55 | ? isActive(item) 56 | ? 'column' 57 | : 'row' 58 | : 'row', 59 | marginBottom: activeItem ? 0 : 10, 60 | }} 61 | > 62 |
78 |
79 |
80 |
90 | {item.title} 91 |
92 |
93 | 94 |
95 |
96 |
97 |
{item.desc}
98 |
99 | {item.view} 100 |
101 |
102 |
109 | {item.body} 110 |
111 | 112 |
113 |
114 |
115 |
116 | ))} 117 |
118 |
119 | ); 120 | }; 121 | 122 | export default Widget; 123 | -------------------------------------------------------------------------------- /demo/src/widgets/clock/component.tsx: -------------------------------------------------------------------------------- 1 | import { Col, Row } from 'antd'; 2 | import moment from 'moment'; 3 | import React, { useCallback, useEffect, useState } from 'react'; 4 | import { useResizeDetector } from 'react-resize-detector'; 5 | import './index.less'; 6 | 7 | const widgetName = 'Clock'; 8 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 9 | 10 | const Widget = (props: any) => { 11 | const {} = props; 12 | const [layout, setLayout] = useState('h'); 13 | const [fontSize, setfontSize] = useState('60px'); 14 | const [degSeconds, setDegSeconds] = useState(0); 15 | const [degMinutes, setDegMinutes] = useState(0); 16 | const [degHours, setDegHours] = useState(0); 17 | const [breathe, setBreathe] = useState(true); 18 | 19 | const clockRun = useCallback(() => { 20 | var date = new Date(), 21 | seconds = date.getSeconds(), 22 | minutes = date.getMinutes(), 23 | hours = date.getHours(); 24 | setDegSeconds((seconds * 360) / 60); 25 | setDegMinutes(((minutes + seconds / 60) * 360) / 60); 26 | setDegHours(((hours + minutes / 60 + seconds / 60 / 60) * 360) / 12); 27 | setBreathe((breathe) => !breathe); 28 | }, []); 29 | 30 | useEffect(() => { 31 | let run = setInterval(() => { 32 | clockRun(); 33 | }, 1000); 34 | return function cleanup() { 35 | clearInterval(run); 36 | }; 37 | }, []); 38 | 39 | const onResize = (w: any, h: any) => { 40 | let layoutTemp: string, fontSizeTemp: string; 41 | if (w < h) { 42 | layoutTemp = 'v'; 43 | fontSizeTemp = h / 6 + 'px'; 44 | } else { 45 | layoutTemp = 'h'; 46 | fontSizeTemp = h / 3 + 'px'; 47 | } 48 | setLayout(layoutTemp); 49 | setfontSize(fontSizeTemp); 50 | }; 51 | 52 | const { ref, width, height } = useResizeDetector({ onResize }); 53 | 54 | return ( 55 |
56 | 57 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
73 |
78 |
83 |
84 |
85 |
86 | 87 | 92 |
93 | {moment().format('HH')} 94 | 102 | {breathe ? ':' : ' '} 103 | 104 | {moment().format('mm')} 105 |
106 |
107 |
108 | {moment().format('YYYY-MM-DD')} 109 |
110 |
111 | {moment().format('dddd')} 112 |
113 |
114 | 115 | 116 | 117 | ); 118 | }; 119 | 120 | export default Widget; 121 | -------------------------------------------------------------------------------- /doc/src/widgets/clock/component.tsx: -------------------------------------------------------------------------------- 1 | import { Col, Row } from 'antd'; 2 | import moment from 'moment'; 3 | import React, { useCallback, useEffect, useState } from 'react'; 4 | import { useResizeDetector } from 'react-resize-detector'; 5 | import './index.less'; 6 | 7 | const widgetName = 'Clock'; 8 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 9 | 10 | const Widget = (props: any) => { 11 | const {} = props; 12 | const [layout, setLayout] = useState('h'); 13 | const [fontSize, setfontSize] = useState('60px'); 14 | const [degSeconds, setDegSeconds] = useState(0); 15 | const [degMinutes, setDegMinutes] = useState(0); 16 | const [degHours, setDegHours] = useState(0); 17 | const [breathe, setBreathe] = useState(true); 18 | 19 | const clockRun = useCallback(() => { 20 | var date = new Date(), 21 | seconds = date.getSeconds(), 22 | minutes = date.getMinutes(), 23 | hours = date.getHours(); 24 | setDegSeconds((seconds * 360) / 60); 25 | setDegMinutes(((minutes + seconds / 60) * 360) / 60); 26 | setDegHours(((hours + minutes / 60 + seconds / 60 / 60) * 360) / 12); 27 | setBreathe((breathe) => !breathe); 28 | }, []); 29 | 30 | useEffect(() => { 31 | let run = setInterval(() => { 32 | clockRun(); 33 | }, 1000); 34 | return function cleanup() { 35 | clearInterval(run); 36 | }; 37 | }, []); 38 | 39 | const onResize = (w: any, h: any) => { 40 | let layoutTemp: string, fontSizeTemp: string; 41 | if (w < h) { 42 | layoutTemp = 'v'; 43 | fontSizeTemp = h / 6 + 'px'; 44 | } else { 45 | layoutTemp = 'h'; 46 | fontSizeTemp = h / 3 + 'px'; 47 | } 48 | setLayout(layoutTemp); 49 | setfontSize(fontSizeTemp); 50 | }; 51 | 52 | const { ref, width, height } = useResizeDetector({ onResize }); 53 | 54 | return ( 55 |
56 | 57 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
73 |
78 |
83 |
84 |
85 |
86 | 87 | 92 |
93 | {moment().format('HH')} 94 | 102 | {breathe ? ':' : ' '} 103 | 104 | {moment().format('mm')} 105 |
106 |
107 |
108 | {moment().format('YYYY-MM-DD')} 109 |
110 |
111 | {moment().format('dddd')} 112 |
113 |
114 | 115 | 116 | 117 | ); 118 | }; 119 | 120 | export default Widget; 121 | -------------------------------------------------------------------------------- /doc/src/widgets/popular/component.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | CloseCircleOutlined, 3 | EllipsisOutlined, 4 | EyeOutlined 5 | } from '@ant-design/icons'; 6 | import _ from 'lodash'; 7 | import React, { useState } from 'react'; 8 | import { List } from './data'; 9 | import './index.less'; 10 | 11 | const widgetName = 'Popular'; 12 | const widgetClassName = 'react-dashboard-widget-' + widgetName; 13 | const Widget = (props: any) => { 14 | const { height } = props; 15 | 16 | const [activeItem, setActiveItem] = useState(null); 17 | 18 | const onItemClick = (e: React.MouseEvent, item: any) => { 19 | setActiveItem(item); 20 | }; 21 | 22 | const isActive = (item: any) => { 23 | return activeItem && _.get(activeItem, 'id') === item.id; 24 | }; 25 | 26 | const onClose = (e: React.MouseEvent) => { 27 | e.stopPropagation(); 28 | e.preventDefault(); 29 | setActiveItem(null); 30 | }; 31 | 32 | 33 | return ( 34 |
35 |
45 |
46 | {List.map((item) => ( 47 |
onItemClick(e, item)} 51 | style={{ 52 | opacity: activeItem ? (isActive(item) ? 1 : 0) : 1, 53 | height: activeItem ? (isActive(item) ? 'auto' : 0) : 'auto', 54 | flexDirection: activeItem 55 | ? isActive(item) 56 | ? 'column' 57 | : 'row' 58 | : 'row', 59 | marginBottom: activeItem ? 0 : 10, 60 | }} 61 | > 62 |
78 |
79 |
80 |
90 | {item.title} 91 |
92 |
93 | 94 |
95 |
96 |
97 |
{item.desc}
98 |
99 | {item.view} 100 |
101 |
102 |
109 | {item.body} 110 |
111 | 112 |
113 |
114 |
115 |
116 | ))} 117 |
118 |
119 | ); 120 | }; 121 | 122 | export default Widget; 123 | -------------------------------------------------------------------------------- /demo/src/widgets/popular/data.ts: -------------------------------------------------------------------------------- 1 | export const List = [ 2 | { 3 | id: 1, 4 | img: 'https://hbimg.huabanimg.com/da7409eba34a5a7b98a9600034a196ca21cc414718296f-ejAJQX_fw658/format/webp', 5 | title: 'Take Me To Your Heart', 6 | desc: 'Johan Bejerholm', 7 | view: 3, 8 | body: `Whenever you need me, I'll be here。 Whenever you're in 9 | trouble, I'm always near。Whenever you feel alone, and you 10 | think everyone has given up。。。Reach out for me, and I will 11 | give you my everlasting love。`, 12 | }, 13 | { 14 | id: 2, 15 | img: 'https://hbimg.huabanimg.com/bc202b79bceadb094e519502a5d38a6b8e42dc2dcb0bd-JpqLYF_fw658/format/webp', 16 | title: 'Only Love', 17 | desc: 'Johan Bejerholm', 18 | view: 2, 19 | body: `I just wish someday and somehow,We can be back together, Together we'll stay,Always and forever。`, 20 | }, 21 | { 22 | id: 3, 23 | img: 'https://hbimg.huabanimg.com/938473baf3edc112dc8277b9f31ab065f799815741f9c-CU7Wz4_fw658/format/webp', 24 | title: 'That Girl', 25 | desc: 'Johan Bejerholm', 26 | view: 23, 27 | body: `Thoughts of you dance through my mind。 Knowing, it is just a matter of time。Wondering。。。 will u ever be mine?You are in my dreams, night。。。 and sometimes。。。 day。The thoughts seem to never fade away。 Corwin Corey Amber`, 28 | }, 29 | { 30 | id: 4, 31 | img: 'https://hbimg.huabanimg.com/7fa599c7b4fa9302e206cf0edfa5f94524d8d118db515-8yu6v5_fw658/format/webp', 32 | title: 'LIKE I WOULD', 33 | desc: 'Johan Bejerholm', 34 | view: 12, 35 | body: `I have searched a thousand years,And I have cried a thousand tears。I found everything I need,You are everything to me。 Barry Fitzpatrick`, 36 | }, 37 | { 38 | id: 5, 39 | img: 'https://hbimg.huabanimg.com/2b629c260d016122c5f9a5405d4801dcc5e1ceca61c70-HbZQaL_fw658/format/webp', 40 | title: 'You Are Not Alone', 41 | desc: 'Johan Bejerholm', 42 | view: 23, 43 | body: `Her gesture, motion, and her smiles,Her wit, her voice my heart beguiles,Beguiles my heart, I know not why,And yet, I'll love her till I die。 Thomas Ford`, 44 | }, 45 | { 46 | id: 6, 47 | img: 'https://hbimg.huabanimg.com/a880f77ef4fadaa493d90f71902de0ef0000d3364694e-tbelhh_fw658/format/webp', 48 | title: 'Free loop', 49 | desc: 'Johan Bejerholm', 50 | view: 36, 51 | body: `You make me feel so happy;Whenever I'm with you。You make me feel so special--This love is too good to be true。 Rosemary Anne Nash`, 52 | }, 53 | { 54 | id: 7, 55 | img: 'https://hbimg.huabanimg.com/f06dd601271be6e3f97115e097333f434a7a08242fa87-Io89I0_fw658/format/webp', 56 | title: 'Trouble is a friend', 57 | desc: 'Johan Bejerholm', 58 | view: 23, 59 | body: ` If you were a teardrop,In my eye,For fear of losing you,I would never cry。And if the golden sun,Should cease to shine its light,Just one smile from you,Would make my whole world bright。 Hannah Jo Kee`, 60 | }, 61 | { 62 | id: 8, 63 | img: 'https://hbimg.huabanimg.com/690ad8b0b830152a3c86d4fb3c90f8edf2612688af0af-FBjP5A_fw658/format/webp', 64 | title: 'Yesterday once more', 65 | desc: 'Johan Bejerholm', 66 | view: 269, 67 | body: `Since the first time I saw you,I felt something inside,I don't know if it's love at first sight,I do know I really like you a lot。 Tanya C Medeiros`, 68 | }, 69 | { 70 | id: 9, 71 | img: 'https://hbimg.huabanimg.com/bfe7f493467f058efced0ecc645e912dc12f9a9b9e152-HiG16T_fw658/format/webp', 72 | title: 'Angel', 73 | desc: 'Johan Bejerholm', 74 | view: 157, 75 | body: `There is a lady sweet and kind, Was never a face so pleased my mind;I did but see her passing by, And yet, I'll love her till I die。 Thomas Ford`, 76 | }, 77 | { 78 | id: 10, 79 | img: 'https://hbimg.huabanimg.com/827ff50cfb57bbac01f86cb76f95a55058a9e90c9b483-B35gkZ_fw658/format/webp', 80 | title: 'thesoundofsilent', 81 | desc: 'Johan Bejerholm', 82 | view: 698, 83 | body: `When I wake up in the morning,You are all I see;When I think about you,And how happy you make me。You're everything I wanted;You're everything I need;I look at you and know;That you are all to me。 Barry Fitzpatrick`, 84 | }, 85 | { 86 | id: 11, 87 | img: 'https://hbimg.huabanimg.com/01308dcce96f800014c94ee8b06038db43766744109ea4-Njdiqp_fw658/format/webp', 88 | title: 'prayer', 89 | desc: 'Johan Bejerholm', 90 | view: 36, 91 | body: `If you were a teardrop;In my eye,For fear of losing you,I would never cry。And if the golden sun,Should cease to shine its light,Just one smile from you,Would make my whole world bright。 Hannah Jo Keen`, 92 | }, 93 | ]; 94 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/index.less: -------------------------------------------------------------------------------- 1 | @import '~react-grid-layout/css/styles.css'; 2 | // @import '~antd/lib/input/style/index.less'; 3 | 4 | 5 | 6 | 7 | .react-resizable { 8 | 9 | position: relative; 10 | } 11 | .react-resizable-handle { 12 | position: absolute; 13 | width: 20px; 14 | height: 20px; 15 | background-repeat: no-repeat; 16 | background-origin: content-box; 17 | box-sizing: border-box; 18 | background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2IDYiIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmYwMCIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iNnB4Ij48ZyBvcGFjaXR5PSIwLjMwMiI+PHBhdGggZD0iTSA2IDYgTCAwIDYgTCAwIDQuMiBMIDQgNC4yIEwgNC4yIDQuMiBMIDQuMiAwIEwgNiAwIEwgNiA2IEwgNiA2IFoiIGZpbGw9IiMwMDAwMDAiLz48L2c+PC9zdmc+'); 19 | background-position: bottom right; 20 | padding: 0 3px 3px 0; 21 | display:none; 22 | } 23 | .react-resizable-handle-sw { 24 | bottom: 0; 25 | left: 0; 26 | cursor: sw-resize; 27 | transform: rotate(90deg); 28 | } 29 | .react-resizable-handle-se { 30 | bottom: 0; 31 | right: 0; 32 | cursor: se-resize; 33 | } 34 | .react-resizable-handle-nw { 35 | top: 0; 36 | left: 0; 37 | cursor: nw-resize; 38 | transform: rotate(180deg); 39 | } 40 | .react-resizable-handle-ne { 41 | top: 0; 42 | right: 0; 43 | cursor: ne-resize; 44 | transform: rotate(270deg); 45 | } 46 | .react-resizable-handle-w, 47 | .react-resizable-handle-e { 48 | top: 50%; 49 | margin-top: -10px; 50 | cursor: ew-resize; 51 | } 52 | .react-resizable-handle-w { 53 | left: 0; 54 | transform: rotate(135deg); 55 | } 56 | .react-resizable-handle-e { 57 | right: 0; 58 | transform: rotate(315deg); 59 | } 60 | .react-resizable-handle-n, 61 | .react-resizable-handle-s { 62 | left: 50%; 63 | margin-left: -10px; 64 | cursor: ns-resize; 65 | } 66 | .react-resizable-handle-n { 67 | top: 0; 68 | transform: rotate(225deg); 69 | } 70 | .react-resizable-handle-s { 71 | bottom: 0; 72 | transform: rotate(45deg); 73 | } 74 | 75 | :root{ 76 | --primary-color:blue; 77 | --component-background:#fff; 78 | } 79 | 80 | 81 | .react-grid-item > .react-resizable-handle { 82 | z-index: 1; 83 | } 84 | .react-dashboard-item-edit{ 85 | .react-resizable-handle { 86 | display:block; 87 | } 88 | } 89 | 90 | .react-dashboard-full { 91 | width: 100%; 92 | height: 100%; 93 | } 94 | .react-dashboard-aligncenter { 95 | display: flex; 96 | justify-content: center; 97 | align-items: center; 98 | } 99 | //空页面样式 100 | .react-dashboard-emptyContent { 101 | // min-height: calc(100vh - 50px - 41px - 50px - 10px - 22px); 102 | display: flex; 103 | justify-content: center; 104 | align-items: center; 105 | } 106 | 107 | 108 | .react-dashboard-item { 109 | position: relative; 110 | // overflow: hidden; 111 | // border:1px solid rgba(128,128,128,0.3); 112 | .react-dashboard-mask { 113 | position: absolute; 114 | top: 0; 115 | left: 0; 116 | z-index: 1; 117 | width: 100%; 118 | height: 100%; 119 | background: rgba(0, 0, 0, 0); 120 | cursor: move; 121 | transition: all 0.3s; 122 | } 123 | 124 | .react-dashboard-configicon { 125 | position: absolute; 126 | top: 0; 127 | right: 30px; 128 | z-index: 1; 129 | display: none; 130 | width: 30px; 131 | height: 30px; 132 | color: #fff; 133 | font-weight: bold; 134 | font-size: 16px; 135 | line-height: 30px; 136 | text-align: center; 137 | background: var(--primary-color); 138 | border-radius: var(--card-border-radius) 0 0 var(--card-border-radius); 139 | cursor: pointer; 140 | } 141 | 142 | .react-dashboard-deleteicon { 143 | position: absolute; 144 | top: 0; 145 | right: 0; 146 | z-index: 1; 147 | display: none; 148 | width: 30px; 149 | height: 30px; 150 | color: #fff; 151 | font-size: 16px; 152 | line-height: 30px; 153 | text-align: center; 154 | background: #f5222d; 155 | border-radius: var(--card-border-radius); 156 | cursor: pointer; 157 | } 158 | 159 | .react-dashboard-configicon + .react-dashboard-deleteicon { 160 | border-radius: 0 var(--card-border-radius) var(--card-border-radius) 0; 161 | } 162 | 163 | &:hover { 164 | .react-dashboard-mask { 165 | background: rgba(0, 0, 0, 0.05); 166 | transition: all 0.3s; 167 | } 168 | 169 | .react-dashboard-configicon { 170 | display: block; 171 | } 172 | 173 | .react-dashboard-deleteicon { 174 | display: block; 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /doc/src/widgets/popular/data.ts: -------------------------------------------------------------------------------- 1 | export const List = [ 2 | { 3 | id: 1, 4 | img: 'https://cdn.dribbble.com/users/1319260/screenshots/16329726/media/c3f00d832cdeb482cba52a6a473d88a0.png?compress=1&resize=400x300', 5 | title: 'Take Me To Your Heart', 6 | desc: 'Johan Bejerholm', 7 | view: 3, 8 | body: `Whenever you need me, I'll be here。 Whenever you're in 9 | trouble, I'm always near。Whenever you feel alone, and you 10 | think everyone has given up。。。Reach out for me, and I will 11 | give you my everlasting love。`, 12 | }, 13 | { 14 | id: 2, 15 | img: 'https://cdn.dribbble.com/users/4335179/screenshots/16323332/media/700459108009c77d83e8a75a891834e9.png?compress=1&resize=400x300', 16 | title: 'Only Love', 17 | desc: 'Johan Bejerholm', 18 | view: 2, 19 | body: `I just wish someday and somehow,We can be back together, Together we'll stay,Always and forever。`, 20 | }, 21 | { 22 | id: 3, 23 | img: 'https://cdn.dribbble.com/users/3812993/screenshots/16326952/media/93cfe22526e7b21e6f38287fc936e708.png?compress=1&resize=400x300', 24 | title: 'That Girl', 25 | desc: 'Johan Bejerholm', 26 | view: 23, 27 | body: `Thoughts of you dance through my mind。 Knowing, it is just a matter of time。Wondering。。。 will u ever be mine?You are in my dreams, night。。。 and sometimes。。。 day。The thoughts seem to never fade away。 Corwin Corey Amber`, 28 | }, 29 | { 30 | id: 4, 31 | img: 'https://cdn.dribbble.com/users/4205502/screenshots/16291726/media/1abf2a786cc29650983d48e72cab2d79.png?compress=1&resize=400x300', 32 | title: 'LIKE I WOULD', 33 | desc: 'Johan Bejerholm', 34 | view: 12, 35 | body: `I have searched a thousand years,And I have cried a thousand tears。I found everything I need,You are everything to me。 Barry Fitzpatrick`, 36 | }, 37 | { 38 | id: 5, 39 | img: 'https://cdn.dribbble.com/users/702789/screenshots/16325312/media/4dec7e6269aa7418e800a1d3c03e9f99.png?compress=1&resize=400x300', 40 | title: 'You Are Not Alone', 41 | desc: 'Johan Bejerholm', 42 | view: 23, 43 | body: `Her gesture, motion, and her smiles,Her wit, her voice my heart beguiles,Beguiles my heart, I know not why,And yet, I'll love her till I die。 Thomas Ford`, 44 | }, 45 | { 46 | id: 6, 47 | img: 'https://cdn.dribbble.com/users/32512/screenshots/16147049/media/9eaf445ca1b3abacada7c9f4871f980c.png?compress=1&resize=400x300', 48 | title: 'Free loop', 49 | desc: 'Johan Bejerholm', 50 | view: 36, 51 | body: `You make me feel so happy;Whenever I'm with you。You make me feel so special--This love is too good to be true。 Rosemary Anne Nash`, 52 | }, 53 | { 54 | id: 7, 55 | img: 'https://cdn.dribbble.com/users/19950/screenshots/16329008/media/9825dd2d17a7941ef98fdb2319c9ea6b.jpeg?compress=1&resize=800x600', 56 | title: 'Trouble is a friend', 57 | desc: 'Johan Bejerholm', 58 | view: 23, 59 | body: ` If you were a teardrop,In my eye,For fear of losing you,I would never cry。And if the golden sun,Should cease to shine its light,Just one smile from you,Would make my whole world bright。 Hannah Jo Kee`, 60 | }, 61 | { 62 | id: 8, 63 | img: 'https://cdn.dribbble.com/users/2598997/screenshots/16326547/media/db44f8eb3cebc789085a78971c647b8e.png?compress=1&resize=400x300', 64 | title: 'Yesterday once more', 65 | desc: 'Johan Bejerholm', 66 | view: 269, 67 | body: `Since the first time I saw you,I felt something inside,I don't know if it's love at first sight,I do know I really like you a lot。 Tanya C Medeiros`, 68 | }, 69 | { 70 | id: 9, 71 | img: 'https://cdn.dribbble.com/users/3281732/screenshots/16318071/media/2dd5358672e6637b1ec7fb06e850c1c9.jpg?compress=1&resize=400x300', 72 | title: 'Angel', 73 | desc: 'Johan Bejerholm', 74 | view: 157, 75 | body: `There is a lady sweet and kind, Was never a face so pleased my mind;I did but see her passing by, And yet, I'll love her till I die。 Thomas Ford`, 76 | }, 77 | { 78 | id: 10, 79 | img: 'https://cdn.dribbble.com/users/1126935/screenshots/16325356/media/0d45ed1a4ca2cd8274d2aab9990e29ba.png?compress=1&resize=400x300', 80 | title: 'thesoundofsilent', 81 | desc: 'Johan Bejerholm', 82 | view: 698, 83 | body: `When I wake up in the morning,You are all I see;When I think about you,And how happy you make me。You're everything I wanted;You're everything I need;I look at you and know;That you are all to me。 Barry Fitzpatrick`, 84 | }, 85 | { 86 | id: 11, 87 | img: 'https://cdn.dribbble.com/users/730703/screenshots/16321137/media/68db2cf9022123e07016b89dbe69546e.jpg?compress=1&resize=800x600', 88 | title: 'prayer', 89 | desc: 'Johan Bejerholm', 90 | view: 36, 91 | body: `If you were a teardrop;In my eye,For fear of losing you,I would never cry。And if the golden sun,Should cease to shine its light,Just one smile from you,Would make my whole world bright。 Hannah Jo Keen`, 92 | }, 93 | ]; 94 | -------------------------------------------------------------------------------- /doc/src/.components/api/index.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from 'antd'; 2 | 3 | export default (props: any) => { 4 | const dataSource = [ 5 | { 6 | prop: `widgets`, 7 | desc: `可选的小程序对象集合`, 8 | type: ( 9 | <> 10 | {`{ 11 | [key: string]`} 12 | :widget{`}`} 13 | 14 | ), 15 | default: ``, 16 | required: `true`, 17 | }, 18 | { 19 | prop: `editMode`, 20 | desc: `是否编辑状态`, 21 | type: `boolean`, 22 | default: `false`, 23 | required: `false`, 24 | }, 25 | { 26 | prop: `defaultLayout`, 27 | desc: `默认布局`, 28 | type: <>LayoutItem[], 29 | default: `[]`, 30 | required: `false`, 31 | }, 32 | { 33 | prop: `widgetWrapClassName`, 34 | desc: `widget容器类名`, 35 | type: `string`, 36 | default: ``, 37 | required: `false`, 38 | }, 39 | { 40 | prop: `widgetWrapStyle`, 41 | desc: `widget容器样式`, 42 | type: `React.CSSProperties`, 43 | default: ``, 44 | required: `false`, 45 | }, 46 | { 47 | prop: `layout`, 48 | desc: `布局数据`, 49 | type: <>LayoutItem[], 50 | default: `null`, 51 | required: `false`, 52 | }, 53 | { 54 | prop: `minHeight`, 55 | desc: `最小高度`, 56 | type: `number`, 57 | default: `300`, 58 | required: `false`, 59 | }, 60 | { 61 | prop: `maxWidgetLength`, 62 | desc: `当前仪表板最大可添加的widget数量`, 63 | type: `number`, 64 | default: `20`, 65 | required: `false`, 66 | }, 67 | { 68 | prop: `toolbar`, 69 | desc: `是否显示默认工具栏`, 70 | type: `boolean`, 71 | default: `true`, 72 | required: `false`, 73 | }, 74 | { 75 | prop: `storageKey`, 76 | desc: `本地存储唯一标识`, 77 | type: `string`, 78 | default: `default`, 79 | required: `false`, 80 | }, 81 | { 82 | prop: `onLayoutChange`, 83 | desc: `布局改变的回调`, 84 | type: `(layout: LayoutsIF) => void`, 85 | default: ``, 86 | required: `false`, 87 | }, 88 | , 89 | { 90 | prop: `onReset`, 91 | desc: `清空按钮的回调`, 92 | type: `(dirtyCurrentLayout: LayoutsIF, currentLayout: LayoutItem) => void`, 93 | default: ``, 94 | required: `false`, 95 | }, 96 | , 97 | { 98 | prop: `onRemoveWidget`, 99 | desc: `删除小程序的回调`, 100 | type: `( 101 | widget: WidgetIF, 102 | dirtyCurrentLayout: LayoutsIF, 103 | currentLayout: LayoutsIF, 104 | ) => void`, 105 | default: ``, 106 | required: `false`, 107 | }, 108 | { 109 | prop: `onAddWidget`, 110 | desc: `添加小程序的回调`, 111 | type: `( 112 | widget: WidgetIF, 113 | dirtyCurrentLayout: LayoutsIF, 114 | currentLayout: LayoutsIF, 115 | ) => void`, 116 | default: ``, 117 | required: `false`, 118 | }, 119 | , 120 | { 121 | prop: `onReload`, 122 | desc: `刷新按钮的回调`, 123 | type: `(currentLayout: LayoutsIF) => void`, 124 | default: ``, 125 | required: `false`, 126 | }, 127 | , 128 | { 129 | prop: `onCancelEdit`, 130 | desc: `取消编辑的回调`, 131 | type: `( 132 | dirtyCurrentLayout: LayoutsIF, 133 | currentLayout: LayoutItem, 134 | ) => void`, 135 | default: ``, 136 | required: `false`, 137 | }, 138 | , 139 | { 140 | prop: `onEdit`, 141 | desc: `进入编辑的回调`, 142 | type: `(currentLayout: LayoutsIF) => void`, 143 | default: ``, 144 | required: `false`, 145 | }, 146 | , 147 | { 148 | prop: `onSave`, 149 | desc: `保存按钮的回调`, 150 | type: `(currentLayout: LayoutsIF) => void`, 151 | default: ``, 152 | required: `false`, 153 | }, 154 | , 155 | { 156 | prop: `onRevert`, 157 | desc: `恢复按钮的回调`, 158 | type: `(dirtyCurrentLayout: LayoutsIF, currentLayout: LayoutItem) => void`, 159 | default: ``, 160 | required: `false`, 161 | }, 162 | ]; 163 | 164 | const columns = [ 165 | { 166 | title: '属性', 167 | dataIndex: 'prop', 168 | key: 'prop', 169 | }, 170 | { 171 | title: '说明', 172 | dataIndex: 'desc', 173 | key: 'desc', 174 | }, 175 | { 176 | title: '类型', 177 | dataIndex: 'type', 178 | key: 'type', 179 | }, 180 | { 181 | title: '默认值', 182 | dataIndex: 'default', 183 | key: 'default', 184 | }, 185 | { 186 | title: '是否必传', 187 | dataIndex: 'required', 188 | key: 'required', 189 | }, 190 | ]; 191 | 192 | return ( 193 |
201 | ); 202 | }; 203 | -------------------------------------------------------------------------------- /doc/src/components/api/index.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from 'antd'; 2 | 3 | export default (props: any) => { 4 | const dataSource = [ 5 | { 6 | prop: `widgets`, 7 | desc: `可选的小程序对象集合`, 8 | type: ( 9 | <> 10 | {`{ 11 | [key: string]`} 12 | :widget{`}`} 13 | 14 | ), 15 | default: ``, 16 | required: `true`, 17 | }, 18 | { 19 | prop: `editMode`, 20 | desc: `是否编辑状态`, 21 | type: `boolean`, 22 | default: `false`, 23 | required: `false`, 24 | }, 25 | { 26 | prop: `defaultLayout`, 27 | desc: `默认布局`, 28 | type: <>LayoutItem[], 29 | default: `[]`, 30 | required: `false`, 31 | }, 32 | { 33 | prop: `widgetWrapClassName`, 34 | desc: `widget容器类名`, 35 | type: `string`, 36 | default: ``, 37 | required: `false`, 38 | }, 39 | { 40 | prop: `widgetWrapStyle`, 41 | desc: `widget容器样式`, 42 | type: `React.CSSProperties`, 43 | default: ``, 44 | required: `false`, 45 | }, 46 | { 47 | prop: `layout`, 48 | desc: `布局数据`, 49 | type: <>LayoutItem[], 50 | default: `null`, 51 | required: `false`, 52 | }, 53 | { 54 | prop: `minHeight`, 55 | desc: `最小高度`, 56 | type: `number`, 57 | default: `300`, 58 | required: `false`, 59 | }, 60 | { 61 | prop: `maxWidgetLength`, 62 | desc: `当前仪表板最大可添加的widget数量`, 63 | type: `number`, 64 | default: `20`, 65 | required: `false`, 66 | }, 67 | { 68 | prop: `toolbar`, 69 | desc: `是否显示默认工具栏`, 70 | type: `boolean`, 71 | default: `true`, 72 | required: `false`, 73 | }, 74 | { 75 | prop: `storageKey`, 76 | desc: `本地存储唯一标识`, 77 | type: `string`, 78 | default: `default`, 79 | required: `false`, 80 | }, 81 | { 82 | prop: `onLayoutChange`, 83 | desc: `布局改变的回调`, 84 | type: `(layout: LayoutsIF) => void`, 85 | default: ``, 86 | required: `false`, 87 | }, 88 | , 89 | { 90 | prop: `onReset`, 91 | desc: `清空按钮的回调`, 92 | type: `(dirtyCurrentLayout: LayoutsIF, currentLayout: LayoutItem) => void`, 93 | default: ``, 94 | required: `false`, 95 | }, 96 | , 97 | { 98 | prop: `onRemoveWidget`, 99 | desc: `删除小程序的回调`, 100 | type: `( 101 | widget: WidgetIF, 102 | dirtyCurrentLayout: LayoutsIF, 103 | currentLayout: LayoutsIF, 104 | ) => void`, 105 | default: ``, 106 | required: `false`, 107 | }, 108 | { 109 | prop: `onAddWidget`, 110 | desc: `添加小程序的回调`, 111 | type: `( 112 | widget: WidgetIF, 113 | dirtyCurrentLayout: LayoutsIF, 114 | currentLayout: LayoutsIF, 115 | ) => void`, 116 | default: ``, 117 | required: `false`, 118 | }, 119 | , 120 | { 121 | prop: `onReload`, 122 | desc: `刷新按钮的回调`, 123 | type: `(currentLayout: LayoutsIF) => void`, 124 | default: ``, 125 | required: `false`, 126 | }, 127 | , 128 | { 129 | prop: `onCancelEdit`, 130 | desc: `取消编辑的回调`, 131 | type: `( 132 | dirtyCurrentLayout: LayoutsIF, 133 | currentLayout: LayoutItem, 134 | ) => void`, 135 | default: ``, 136 | required: `false`, 137 | }, 138 | , 139 | { 140 | prop: `onEdit`, 141 | desc: `进入编辑的回调`, 142 | type: `(currentLayout: LayoutsIF) => void`, 143 | default: ``, 144 | required: `false`, 145 | }, 146 | , 147 | { 148 | prop: `onSave`, 149 | desc: `保存按钮的回调`, 150 | type: `(currentLayout: LayoutsIF) => void`, 151 | default: ``, 152 | required: `false`, 153 | }, 154 | , 155 | { 156 | prop: `onRevert`, 157 | desc: `恢复按钮的回调`, 158 | type: `(dirtyCurrentLayout: LayoutsIF, currentLayout: LayoutItem) => void`, 159 | default: ``, 160 | required: `false`, 161 | }, 162 | ]; 163 | 164 | const columns = [ 165 | { 166 | title: '属性', 167 | dataIndex: 'prop', 168 | key: 'prop', 169 | }, 170 | { 171 | title: '说明', 172 | dataIndex: 'desc', 173 | key: 'desc', 174 | }, 175 | { 176 | title: '类型', 177 | dataIndex: 'type', 178 | key: 'type', 179 | }, 180 | { 181 | title: '默认值', 182 | dataIndex: 'default', 183 | key: 'default', 184 | }, 185 | { 186 | title: '是否必传', 187 | dataIndex: 'required', 188 | key: 'required', 189 | }, 190 | ]; 191 | 192 | return ( 193 |
201 | ); 202 | }; 203 | -------------------------------------------------------------------------------- /demo/.umi/core/pluginConfig.d.ts: -------------------------------------------------------------------------------- 1 | // Created by Umi Plugin 2 | 3 | export interface IConfigFromPlugins { 4 | "404"?: boolean 5 | routes?: { 6 | /** 7 | * Any valid URL path 8 | */ 9 | path?: string 10 | /** 11 | * A React component to render only when the location matches. 12 | */ 13 | component?: (string | (() => any)) 14 | wrappers?: string[] 15 | /** 16 | * navigate to a new location 17 | */ 18 | redirect?: string 19 | /** 20 | * When true, the active class/style will only be applied if the location is matched exactly. 21 | */ 22 | exact?: boolean 23 | routes?: any[] 24 | [k: string]: any 25 | }[] 26 | history?: { 27 | type?: ("browser" | "hash" | "memory") 28 | options?: { 29 | 30 | } 31 | } 32 | polyfill?: { 33 | imports?: string[] 34 | } 35 | alias?: { 36 | 37 | } 38 | analyze?: { 39 | analyzerMode?: ("server" | "static" | "disabled") 40 | analyzerHost?: string 41 | analyzerPort?: any 42 | openAnalyzer?: boolean 43 | generateStatsFile?: boolean 44 | statsFilename?: string 45 | logLevel?: ("info" | "warn" | "error" | "silent") 46 | defaultSizes?: ("stat" | "parsed" | "gzip") 47 | [k: string]: any 48 | } 49 | /** 50 | * postcss autoprefixer, default flexbox: no-2009 51 | */ 52 | autoprefixer?: { 53 | 54 | } 55 | base?: string 56 | chainWebpack?: (() => any) 57 | chunks?: string[] 58 | /** 59 | * more css-loader options see https://webpack.js.org/loaders/css-loader/#options 60 | */ 61 | cssLoader?: { 62 | url?: (boolean | (() => any)) 63 | import?: (boolean | (() => any)) 64 | modules?: (boolean | string | { 65 | 66 | }) 67 | sourceMap?: boolean 68 | importLoaders?: number 69 | onlyLocals?: boolean 70 | esModule?: boolean 71 | localsConvention?: ("asIs" | "camelCase" | "camelCaseOnly" | "dashes" | "dashesOnly") 72 | } 73 | cssModulesTypescriptLoader?: { 74 | mode?: ("emit" | "verify") 75 | } 76 | cssnano?: { 77 | 78 | } 79 | copy?: any[] 80 | define?: { 81 | 82 | } 83 | devScripts?: { 84 | 85 | } 86 | /** 87 | * devServer configs 88 | */ 89 | devServer?: { 90 | /** 91 | * devServer port, default 8000 92 | */ 93 | port?: number 94 | host?: string 95 | https?: ({ 96 | key?: string 97 | cert?: string 98 | [k: string]: any 99 | } | boolean) 100 | headers?: { 101 | 102 | } 103 | writeToDisk?: (boolean | (() => any)) 104 | [k: string]: any 105 | } 106 | devtool?: string 107 | /** 108 | * Code splitting for performance optimization 109 | */ 110 | dynamicImport?: { 111 | /** 112 | * loading the component before loaded 113 | */ 114 | loading?: string 115 | } 116 | /** 117 | * Code splitting for import statement syntax 118 | */ 119 | dynamicImportSyntax?: { 120 | 121 | } 122 | exportStatic?: { 123 | htmlSuffix?: boolean 124 | dynamicRoot?: boolean 125 | /** 126 | * extra render paths only enable in ssr 127 | */ 128 | extraRoutePaths?: (() => any) 129 | } 130 | externals?: ({ 131 | 132 | } | string | (() => any)) 133 | extraBabelIncludes?: any[] 134 | extraBabelPlugins?: any[] 135 | extraBabelPresets?: any[] 136 | extraPostCSSPlugins?: any[] 137 | /** 138 | * fork-ts-checker-webpack-plugin options see https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#options 139 | */ 140 | forkTSChecker?: { 141 | async?: boolean 142 | typescript?: (boolean | { 143 | 144 | }) 145 | eslint?: { 146 | 147 | } 148 | issue?: { 149 | 150 | } 151 | formatter?: (string | { 152 | 153 | }) 154 | logger?: { 155 | 156 | } 157 | [k: string]: any 158 | } 159 | fastRefresh?: { 160 | 161 | } 162 | hash?: boolean 163 | ignoreMomentLocale?: boolean 164 | inlineLimit?: number 165 | lessLoader?: { 166 | 167 | } 168 | manifest?: { 169 | fileName?: string 170 | publicPath?: "" 171 | basePath?: string 172 | writeToFileEmit?: boolean 173 | } 174 | /** 175 | * open mfsu feature 176 | */ 177 | mfsu?: { 178 | development?: { 179 | output?: string 180 | } 181 | production?: { 182 | output?: string 183 | } 184 | mfName?: string 185 | exportAllMembers?: { 186 | 187 | } 188 | chunks?: string[] 189 | ignoreNodeBuiltInModules?: boolean 190 | } 191 | mountElementId?: "" 192 | mpa?: { 193 | 194 | } 195 | nodeModulesTransform?: { 196 | type?: ("all" | "none") 197 | exclude?: string[] 198 | } 199 | outputPath?: "" 200 | plugins?: string[] 201 | postcssLoader?: { 202 | 203 | } 204 | presets?: string[] 205 | proxy?: { 206 | 207 | } 208 | publicPath?: string 209 | runtimePublicPath?: boolean 210 | ssr?: { 211 | /** 212 | * force execing Page getInitialProps functions 213 | */ 214 | forceInitial?: boolean 215 | /** 216 | * remove window.g_initialProps in html 217 | */ 218 | removeWindowInitialProps?: boolean 219 | /** 220 | * disable serve-side render in umi dev mode. 221 | */ 222 | devServerRender?: boolean 223 | mode?: ("stream" | "string") 224 | /** 225 | * static markup in static site 226 | */ 227 | staticMarkup?: boolean 228 | } 229 | singular?: boolean 230 | styleLoader?: { 231 | 232 | } 233 | targets?: { 234 | 235 | } 236 | terserOptions?: { 237 | 238 | } 239 | theme?: { 240 | 241 | } 242 | runtimeHistory?: { 243 | 244 | } 245 | webpack5?: { 246 | lazyCompilation?: { 247 | entries?: boolean 248 | imports?: boolean 249 | test?: any 250 | } 251 | } 252 | workerLoader?: { 253 | 254 | } 255 | favicon?: string 256 | headScripts?: any[] 257 | links?: any[] 258 | metas?: any[] 259 | scripts?: any[] 260 | styles?: any[] 261 | title?: string 262 | mock?: { 263 | exclude?: string[] 264 | } 265 | [k: string]: any 266 | } 267 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/style/spin.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */ 2 | /* stylelint-disable no-duplicate-selectors */ 3 | /* stylelint-disable */ 4 | /* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */ 5 | .ant-spin { 6 | box-sizing: border-box; 7 | margin: 0; 8 | padding: 0; 9 | color: rgba(0, 0, 0, 0.85); 10 | font-size: 14px; 11 | font-variant: tabular-nums; 12 | line-height: 1.5715; 13 | list-style: none; 14 | font-feature-settings: 'tnum'; 15 | position: absolute; 16 | display: none; 17 | color: #1890ff; 18 | text-align: center; 19 | vertical-align: middle; 20 | opacity: 0; 21 | transition: transform 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86); 22 | } 23 | .ant-spin-spinning { 24 | position: static; 25 | display: inline-block; 26 | opacity: 1; 27 | } 28 | .ant-spin-nested-loading { 29 | position: relative; 30 | } 31 | .ant-spin-nested-loading > div > .ant-spin { 32 | position: absolute; 33 | top: 0; 34 | left: 0; 35 | z-index: 4; 36 | display: block; 37 | width: 100%; 38 | height: 100%; 39 | max-height: 400px; 40 | } 41 | .ant-spin-nested-loading > div > .ant-spin .ant-spin-dot { 42 | position: absolute; 43 | top: 50%; 44 | left: 50%; 45 | margin: -10px; 46 | } 47 | .ant-spin-nested-loading > div > .ant-spin .ant-spin-text { 48 | position: absolute; 49 | top: 50%; 50 | width: 100%; 51 | padding-top: 5px; 52 | text-shadow: 0 1px 2px #fff; 53 | } 54 | .ant-spin-nested-loading > div > .ant-spin.ant-spin-show-text .ant-spin-dot { 55 | margin-top: -20px; 56 | } 57 | .ant-spin-nested-loading > div > .ant-spin-sm .ant-spin-dot { 58 | margin: -7px; 59 | } 60 | .ant-spin-nested-loading > div > .ant-spin-sm .ant-spin-text { 61 | padding-top: 2px; 62 | } 63 | .ant-spin-nested-loading > div > .ant-spin-sm.ant-spin-show-text .ant-spin-dot { 64 | margin-top: -17px; 65 | } 66 | .ant-spin-nested-loading > div > .ant-spin-lg .ant-spin-dot { 67 | margin: -16px; 68 | } 69 | .ant-spin-nested-loading > div > .ant-spin-lg .ant-spin-text { 70 | padding-top: 11px; 71 | } 72 | .ant-spin-nested-loading > div > .ant-spin-lg.ant-spin-show-text .ant-spin-dot { 73 | margin-top: -26px; 74 | } 75 | .ant-spin-container { 76 | position: relative; 77 | transition: opacity 0.3s; 78 | } 79 | .ant-spin-container::after { 80 | position: absolute; 81 | top: 0; 82 | right: 0; 83 | bottom: 0; 84 | left: 0; 85 | z-index: 10; 86 | display: none \9; 87 | width: 100%; 88 | height: 100%; 89 | background: #fff; 90 | opacity: 0; 91 | transition: all 0.3s; 92 | content: ''; 93 | pointer-events: none; 94 | } 95 | .ant-spin-blur { 96 | clear: both; 97 | overflow: hidden; 98 | opacity: 0.5; 99 | -webkit-user-select: none; 100 | -moz-user-select: none; 101 | -ms-user-select: none; 102 | user-select: none; 103 | pointer-events: none; 104 | } 105 | .ant-spin-blur::after { 106 | opacity: 0.4; 107 | pointer-events: auto; 108 | } 109 | .ant-spin-tip { 110 | color: rgba(0, 0, 0, 0.45); 111 | } 112 | .ant-spin-dot { 113 | position: relative; 114 | display: inline-block; 115 | font-size: 20px; 116 | width: 1em; 117 | height: 1em; 118 | } 119 | .ant-spin-dot-item { 120 | position: absolute; 121 | display: block; 122 | width: 9px; 123 | height: 9px; 124 | background-color: #1890ff; 125 | border-radius: 100%; 126 | transform: scale(0.75); 127 | transform-origin: 50% 50%; 128 | opacity: 0.3; 129 | -webkit-animation: antSpinMove 1s infinite linear alternate; 130 | animation: antSpinMove 1s infinite linear alternate; 131 | } 132 | .ant-spin-dot-item:nth-child(1) { 133 | top: 0; 134 | left: 0; 135 | } 136 | .ant-spin-dot-item:nth-child(2) { 137 | top: 0; 138 | right: 0; 139 | -webkit-animation-delay: 0.4s; 140 | animation-delay: 0.4s; 141 | } 142 | .ant-spin-dot-item:nth-child(3) { 143 | right: 0; 144 | bottom: 0; 145 | -webkit-animation-delay: 0.8s; 146 | animation-delay: 0.8s; 147 | } 148 | .ant-spin-dot-item:nth-child(4) { 149 | bottom: 0; 150 | left: 0; 151 | -webkit-animation-delay: 1.2s; 152 | animation-delay: 1.2s; 153 | } 154 | .ant-spin-dot-spin { 155 | transform: rotate(45deg); 156 | -webkit-animation: antRotate 1.2s infinite linear; 157 | animation: antRotate 1.2s infinite linear; 158 | } 159 | .ant-spin-sm .ant-spin-dot { 160 | font-size: 14px; 161 | } 162 | .ant-spin-sm .ant-spin-dot i { 163 | width: 6px; 164 | height: 6px; 165 | } 166 | .ant-spin-lg .ant-spin-dot { 167 | font-size: 32px; 168 | } 169 | .ant-spin-lg .ant-spin-dot i { 170 | width: 14px; 171 | height: 14px; 172 | } 173 | .ant-spin.ant-spin-show-text .ant-spin-text { 174 | display: block; 175 | } 176 | @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { 177 | /* IE10+ */ 178 | .ant-spin-blur { 179 | background: #fff; 180 | opacity: 0.5; 181 | } 182 | } 183 | @-webkit-keyframes antSpinMove { 184 | to { 185 | opacity: 1; 186 | } 187 | } 188 | @keyframes antSpinMove { 189 | to { 190 | opacity: 1; 191 | } 192 | } 193 | @-webkit-keyframes antRotate { 194 | to { 195 | transform: rotate(405deg); 196 | } 197 | } 198 | @keyframes antRotate { 199 | to { 200 | transform: rotate(405deg); 201 | } 202 | } 203 | .ant-spin-rtl { 204 | direction: rtl; 205 | } 206 | .ant-spin-rtl .ant-spin-dot-spin { 207 | transform: rotate(-45deg); 208 | -webkit-animation-name: antRotateRtl; 209 | animation-name: antRotateRtl; 210 | } 211 | @-webkit-keyframes antRotateRtl { 212 | to { 213 | transform: rotate(-405deg); 214 | } 215 | } 216 | @keyframes antRotateRtl { 217 | to { 218 | transform: rotate(-405deg); 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/style/modal.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */ 2 | /* stylelint-disable no-duplicate-selectors */ 3 | /* stylelint-disable */ 4 | /* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */ 5 | .ant-drawer { 6 | position: fixed; 7 | z-index: 1000; 8 | width: 0%; 9 | height: 100%; 10 | transition: transform 0.3s cubic-bezier(0.7, 0.3, 0.1, 1), height 0s ease 0.3s, width 0s ease 0.3s; 11 | } 12 | .ant-drawer > * { 13 | transition: transform 0.3s cubic-bezier(0.7, 0.3, 0.1, 1), box-shadow 0.3s cubic-bezier(0.7, 0.3, 0.1, 1); 14 | } 15 | .ant-drawer-content-wrapper { 16 | position: absolute; 17 | width: 100%; 18 | height: 100%; 19 | } 20 | .ant-drawer .ant-drawer-content { 21 | width: 100%; 22 | height: 100%; 23 | } 24 | .ant-drawer-left, 25 | .ant-drawer-right { 26 | top: 0; 27 | width: 0%; 28 | height: 100%; 29 | } 30 | .ant-drawer-left .ant-drawer-content-wrapper, 31 | .ant-drawer-right .ant-drawer-content-wrapper { 32 | height: 100%; 33 | } 34 | .ant-drawer-left.ant-drawer-open, 35 | .ant-drawer-right.ant-drawer-open { 36 | width: 100%; 37 | transition: transform 0.3s cubic-bezier(0.7, 0.3, 0.1, 1); 38 | } 39 | .ant-drawer-left { 40 | left: 0; 41 | } 42 | .ant-drawer-left .ant-drawer-content-wrapper { 43 | left: 0; 44 | } 45 | .ant-drawer-left.ant-drawer-open .ant-drawer-content-wrapper { 46 | box-shadow: 6px 0 16px -8px rgba(0, 0, 0, 0.08), 9px 0 28px 0 rgba(0, 0, 0, 0.05), 12px 0 48px 16px rgba(0, 0, 0, 0.03); 47 | } 48 | .ant-drawer-right { 49 | right: 0; 50 | } 51 | .ant-drawer-right .ant-drawer-content-wrapper { 52 | right: 0; 53 | } 54 | .ant-drawer-right.ant-drawer-open .ant-drawer-content-wrapper { 55 | box-shadow: -6px 0 16px -8px rgba(0, 0, 0, 0.08), -9px 0 28px 0 rgba(0, 0, 0, 0.05), -12px 0 48px 16px rgba(0, 0, 0, 0.03); 56 | } 57 | .ant-drawer-right.ant-drawer-open.no-mask { 58 | right: 1px; 59 | transform: translateX(1px); 60 | } 61 | .ant-drawer-top, 62 | .ant-drawer-bottom { 63 | left: 0; 64 | width: 100%; 65 | height: 0%; 66 | } 67 | .ant-drawer-top .ant-drawer-content-wrapper, 68 | .ant-drawer-bottom .ant-drawer-content-wrapper { 69 | width: 100%; 70 | } 71 | .ant-drawer-top.ant-drawer-open, 72 | .ant-drawer-bottom.ant-drawer-open { 73 | height: 100%; 74 | transition: transform 0.3s cubic-bezier(0.7, 0.3, 0.1, 1); 75 | } 76 | .ant-drawer-top { 77 | top: 0; 78 | } 79 | .ant-drawer-top.ant-drawer-open .ant-drawer-content-wrapper { 80 | box-shadow: 0 6px 16px -8px rgba(0, 0, 0, 0.08), 0 9px 28px 0 rgba(0, 0, 0, 0.05), 0 12px 48px 16px rgba(0, 0, 0, 0.03); 81 | } 82 | .ant-drawer-bottom { 83 | bottom: 0; 84 | } 85 | .ant-drawer-bottom .ant-drawer-content-wrapper { 86 | bottom: 0; 87 | } 88 | .ant-drawer-bottom.ant-drawer-open .ant-drawer-content-wrapper { 89 | box-shadow: 0 -6px 16px -8px rgba(0, 0, 0, 0.08), 0 -9px 28px 0 rgba(0, 0, 0, 0.05), 0 -12px 48px 16px rgba(0, 0, 0, 0.03); 90 | } 91 | .ant-drawer-bottom.ant-drawer-open.no-mask { 92 | bottom: 1px; 93 | transform: translateY(1px); 94 | } 95 | .ant-drawer.ant-drawer-open .ant-drawer-mask { 96 | height: 100%; 97 | opacity: 1; 98 | transition: none; 99 | -webkit-animation: antdDrawerFadeIn 0.3s cubic-bezier(0.7, 0.3, 0.1, 1); 100 | animation: antdDrawerFadeIn 0.3s cubic-bezier(0.7, 0.3, 0.1, 1); 101 | pointer-events: auto; 102 | } 103 | .ant-drawer-title { 104 | margin: 0; 105 | color: rgba(0, 0, 0, 0.85); 106 | font-weight: 500; 107 | font-size: 16px; 108 | line-height: 22px; 109 | } 110 | .ant-drawer-content { 111 | position: relative; 112 | z-index: 1; 113 | overflow: auto; 114 | background-color: #fff; 115 | background-clip: padding-box; 116 | border: 0; 117 | } 118 | .ant-drawer-close { 119 | position: absolute; 120 | top: 0; 121 | right: 0; 122 | z-index: 10; 123 | display: block; 124 | padding: 20px; 125 | color: rgba(0, 0, 0, 0.45); 126 | font-weight: 700; 127 | font-size: 16px; 128 | font-style: normal; 129 | line-height: 1; 130 | text-align: center; 131 | text-transform: none; 132 | text-decoration: none; 133 | background: transparent; 134 | border: 0; 135 | outline: 0; 136 | cursor: pointer; 137 | transition: color 0.3s; 138 | text-rendering: auto; 139 | } 140 | .ant-drawer-close:focus, 141 | .ant-drawer-close:hover { 142 | color: rgba(0, 0, 0, 0.75); 143 | text-decoration: none; 144 | } 145 | .ant-drawer-header-no-title .ant-drawer-close { 146 | margin-right: var(--scroll-bar); 147 | /* stylelint-disable-next-line function-calc-no-invalid */ 148 | padding-right: calc(20px - var(--scroll-bar)); 149 | } 150 | .ant-drawer-header { 151 | position: relative; 152 | padding: 16px 24px; 153 | color: rgba(0, 0, 0, 0.85); 154 | background: #fff; 155 | border-bottom: 1px solid #f0f0f0; 156 | border-radius: 2px 2px 0 0; 157 | } 158 | .ant-drawer-header-no-title { 159 | color: rgba(0, 0, 0, 0.85); 160 | background: #fff; 161 | } 162 | .ant-drawer-wrapper-body { 163 | display: flex; 164 | flex-direction: column; 165 | flex-wrap: nowrap; 166 | width: 100%; 167 | height: 100%; 168 | } 169 | .ant-drawer-body { 170 | flex-grow: 1; 171 | padding: 24px; 172 | overflow: auto; 173 | font-size: 14px; 174 | line-height: 1.5715; 175 | word-wrap: break-word; 176 | } 177 | .ant-drawer-footer { 178 | flex-shrink: 0; 179 | padding: 10px 16px; 180 | border-top: 1px solid #f0f0f0; 181 | } 182 | .ant-drawer-mask { 183 | position: absolute; 184 | top: 0; 185 | left: 0; 186 | width: 100%; 187 | height: 0; 188 | background-color: rgba(0, 0, 0, 0.45); 189 | opacity: 0; 190 | filter: alpha(opacity=45); 191 | transition: opacity 0.3s linear, height 0s ease 0.3s; 192 | pointer-events: none; 193 | } 194 | .ant-drawer-open-content { 195 | box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05); 196 | } 197 | .ant-drawer .ant-picker-clear { 198 | background: #fff; 199 | } 200 | @-webkit-keyframes antdDrawerFadeIn { 201 | 0% { 202 | opacity: 0; 203 | } 204 | 100% { 205 | opacity: 1; 206 | } 207 | } 208 | @keyframes antdDrawerFadeIn { 209 | 0% { 210 | opacity: 0; 211 | } 212 | 100% { 213 | opacity: 1; 214 | } 215 | } 216 | .ant-drawer-rtl { 217 | direction: rtl; 218 | } 219 | .ant-drawer-rtl .ant-drawer-close { 220 | right: auto; 221 | left: 0; 222 | } 223 | -------------------------------------------------------------------------------- /doc/src/package/dashboard/style/tooltip.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */ 2 | /* stylelint-disable no-duplicate-selectors */ 3 | /* stylelint-disable */ 4 | /* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */ 5 | .ant-tooltip { 6 | box-sizing: border-box; 7 | margin: 0; 8 | padding: 0; 9 | color: rgba(0, 0, 0, 0.85); 10 | font-size: 14px; 11 | font-variant: tabular-nums; 12 | line-height: 1.5715; 13 | list-style: none; 14 | font-feature-settings: 'tnum'; 15 | position: absolute; 16 | z-index: 1070; 17 | display: block; 18 | width: -webkit-max-content; 19 | width: -moz-max-content; 20 | width: max-content; 21 | max-width: 250px; 22 | visibility: visible; 23 | } 24 | .ant-tooltip-hidden { 25 | display: none; 26 | } 27 | .ant-tooltip-placement-top, 28 | .ant-tooltip-placement-topLeft, 29 | .ant-tooltip-placement-topRight { 30 | padding-bottom: 8px; 31 | } 32 | .ant-tooltip-placement-right, 33 | .ant-tooltip-placement-rightTop, 34 | .ant-tooltip-placement-rightBottom { 35 | padding-left: 8px; 36 | } 37 | .ant-tooltip-placement-bottom, 38 | .ant-tooltip-placement-bottomLeft, 39 | .ant-tooltip-placement-bottomRight { 40 | padding-top: 8px; 41 | } 42 | .ant-tooltip-placement-left, 43 | .ant-tooltip-placement-leftTop, 44 | .ant-tooltip-placement-leftBottom { 45 | padding-right: 8px; 46 | } 47 | .ant-tooltip-inner { 48 | min-width: 30px; 49 | min-height: 32px; 50 | padding: 6px 8px; 51 | color: #fff; 52 | text-align: left; 53 | text-decoration: none; 54 | word-wrap: break-word; 55 | background-color: rgba(0, 0, 0, 0.75); 56 | border-radius: 2px; 57 | box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05); 58 | } 59 | .ant-tooltip-arrow { 60 | position: absolute; 61 | display: block; 62 | width: 13.07106781px; 63 | height: 13.07106781px; 64 | overflow: hidden; 65 | background: transparent; 66 | pointer-events: none; 67 | } 68 | .ant-tooltip-arrow-content { 69 | position: absolute; 70 | top: 0; 71 | right: 0; 72 | bottom: 0; 73 | left: 0; 74 | display: block; 75 | width: 5px; 76 | height: 5px; 77 | margin: auto; 78 | background-color: rgba(0, 0, 0, 0.75); 79 | content: ''; 80 | pointer-events: auto; 81 | } 82 | .ant-tooltip-placement-top .ant-tooltip-arrow, 83 | .ant-tooltip-placement-topLeft .ant-tooltip-arrow, 84 | .ant-tooltip-placement-topRight .ant-tooltip-arrow { 85 | bottom: -5.07106781px; 86 | } 87 | .ant-tooltip-placement-top .ant-tooltip-arrow-content, 88 | .ant-tooltip-placement-topLeft .ant-tooltip-arrow-content, 89 | .ant-tooltip-placement-topRight .ant-tooltip-arrow-content { 90 | box-shadow: 3px 3px 7px rgba(0, 0, 0, 0.07); 91 | transform: translateY(-6.53553391px) rotate(45deg); 92 | } 93 | .ant-tooltip-placement-top .ant-tooltip-arrow { 94 | left: 50%; 95 | transform: translateX(-50%); 96 | } 97 | .ant-tooltip-placement-topLeft .ant-tooltip-arrow { 98 | left: 13px; 99 | } 100 | .ant-tooltip-placement-topRight .ant-tooltip-arrow { 101 | right: 13px; 102 | } 103 | .ant-tooltip-placement-right .ant-tooltip-arrow, 104 | .ant-tooltip-placement-rightTop .ant-tooltip-arrow, 105 | .ant-tooltip-placement-rightBottom .ant-tooltip-arrow { 106 | left: -5.07106781px; 107 | } 108 | .ant-tooltip-placement-right .ant-tooltip-arrow-content, 109 | .ant-tooltip-placement-rightTop .ant-tooltip-arrow-content, 110 | .ant-tooltip-placement-rightBottom .ant-tooltip-arrow-content { 111 | box-shadow: -3px 3px 7px rgba(0, 0, 0, 0.07); 112 | transform: translateX(6.53553391px) rotate(45deg); 113 | } 114 | .ant-tooltip-placement-right .ant-tooltip-arrow { 115 | top: 50%; 116 | transform: translateY(-50%); 117 | } 118 | .ant-tooltip-placement-rightTop .ant-tooltip-arrow { 119 | top: 5px; 120 | } 121 | .ant-tooltip-placement-rightBottom .ant-tooltip-arrow { 122 | bottom: 5px; 123 | } 124 | .ant-tooltip-placement-left .ant-tooltip-arrow, 125 | .ant-tooltip-placement-leftTop .ant-tooltip-arrow, 126 | .ant-tooltip-placement-leftBottom .ant-tooltip-arrow { 127 | right: -5.07106781px; 128 | } 129 | .ant-tooltip-placement-left .ant-tooltip-arrow-content, 130 | .ant-tooltip-placement-leftTop .ant-tooltip-arrow-content, 131 | .ant-tooltip-placement-leftBottom .ant-tooltip-arrow-content { 132 | box-shadow: 3px -3px 7px rgba(0, 0, 0, 0.07); 133 | transform: translateX(-6.53553391px) rotate(45deg); 134 | } 135 | .ant-tooltip-placement-left .ant-tooltip-arrow { 136 | top: 50%; 137 | transform: translateY(-50%); 138 | } 139 | .ant-tooltip-placement-leftTop .ant-tooltip-arrow { 140 | top: 5px; 141 | } 142 | .ant-tooltip-placement-leftBottom .ant-tooltip-arrow { 143 | bottom: 5px; 144 | } 145 | .ant-tooltip-placement-bottom .ant-tooltip-arrow, 146 | .ant-tooltip-placement-bottomLeft .ant-tooltip-arrow, 147 | .ant-tooltip-placement-bottomRight .ant-tooltip-arrow { 148 | top: -5.07106781px; 149 | } 150 | .ant-tooltip-placement-bottom .ant-tooltip-arrow-content, 151 | .ant-tooltip-placement-bottomLeft .ant-tooltip-arrow-content, 152 | .ant-tooltip-placement-bottomRight .ant-tooltip-arrow-content { 153 | box-shadow: -3px -3px 7px rgba(0, 0, 0, 0.07); 154 | transform: translateY(6.53553391px) rotate(45deg); 155 | } 156 | .ant-tooltip-placement-bottom .ant-tooltip-arrow { 157 | left: 50%; 158 | transform: translateX(-50%); 159 | } 160 | .ant-tooltip-placement-bottomLeft .ant-tooltip-arrow { 161 | left: 13px; 162 | } 163 | .ant-tooltip-placement-bottomRight .ant-tooltip-arrow { 164 | right: 13px; 165 | } 166 | .ant-tooltip-pink .ant-tooltip-inner { 167 | background-color: #eb2f96; 168 | } 169 | .ant-tooltip-pink .ant-tooltip-arrow-content { 170 | background-color: #eb2f96; 171 | } 172 | .ant-tooltip-magenta .ant-tooltip-inner { 173 | background-color: #eb2f96; 174 | } 175 | .ant-tooltip-magenta .ant-tooltip-arrow-content { 176 | background-color: #eb2f96; 177 | } 178 | .ant-tooltip-red .ant-tooltip-inner { 179 | background-color: #f5222d; 180 | } 181 | .ant-tooltip-red .ant-tooltip-arrow-content { 182 | background-color: #f5222d; 183 | } 184 | .ant-tooltip-volcano .ant-tooltip-inner { 185 | background-color: #fa541c; 186 | } 187 | .ant-tooltip-volcano .ant-tooltip-arrow-content { 188 | background-color: #fa541c; 189 | } 190 | .ant-tooltip-orange .ant-tooltip-inner { 191 | background-color: #fa8c16; 192 | } 193 | .ant-tooltip-orange .ant-tooltip-arrow-content { 194 | background-color: #fa8c16; 195 | } 196 | .ant-tooltip-yellow .ant-tooltip-inner { 197 | background-color: #fadb14; 198 | } 199 | .ant-tooltip-yellow .ant-tooltip-arrow-content { 200 | background-color: #fadb14; 201 | } 202 | .ant-tooltip-gold .ant-tooltip-inner { 203 | background-color: #faad14; 204 | } 205 | .ant-tooltip-gold .ant-tooltip-arrow-content { 206 | background-color: #faad14; 207 | } 208 | .ant-tooltip-cyan .ant-tooltip-inner { 209 | background-color: #13c2c2; 210 | } 211 | .ant-tooltip-cyan .ant-tooltip-arrow-content { 212 | background-color: #13c2c2; 213 | } 214 | .ant-tooltip-lime .ant-tooltip-inner { 215 | background-color: #a0d911; 216 | } 217 | .ant-tooltip-lime .ant-tooltip-arrow-content { 218 | background-color: #a0d911; 219 | } 220 | .ant-tooltip-green .ant-tooltip-inner { 221 | background-color: #52c41a; 222 | } 223 | .ant-tooltip-green .ant-tooltip-arrow-content { 224 | background-color: #52c41a; 225 | } 226 | .ant-tooltip-blue .ant-tooltip-inner { 227 | background-color: #1890ff; 228 | } 229 | .ant-tooltip-blue .ant-tooltip-arrow-content { 230 | background-color: #1890ff; 231 | } 232 | .ant-tooltip-geekblue .ant-tooltip-inner { 233 | background-color: #2f54eb; 234 | } 235 | .ant-tooltip-geekblue .ant-tooltip-arrow-content { 236 | background-color: #2f54eb; 237 | } 238 | .ant-tooltip-purple .ant-tooltip-inner { 239 | background-color: #722ed1; 240 | } 241 | .ant-tooltip-purple .ant-tooltip-arrow-content { 242 | background-color: #722ed1; 243 | } 244 | .ant-tooltip-rtl { 245 | direction: rtl; 246 | } 247 | .ant-tooltip-rtl .ant-tooltip-inner { 248 | text-align: right; 249 | } 250 | --------------------------------------------------------------------------------