├── .gitignore ├── .babelrc ├── .eslintignore ├── src ├── component │ ├── use │ │ ├── listLoading │ │ ├── useRollNotice.de │ │ ├── useTabSwitch.de │ │ ├── useMarquee.de │ │ ├── useSpin.de │ │ ├── useVerify.de │ │ └── useDialog.de │ ├── ListLoading │ │ ├── index.js │ │ └── listloading.less │ ├── RollNotice │ │ ├── demo.js │ │ ├── notice.less │ │ └── index.js │ ├── TabSwitch │ │ ├── demo.js │ │ ├── tabswitch.less │ │ └── index.js │ ├── Marquee │ │ ├── demo.js │ │ ├── marquee.less │ │ └── index.js │ ├── Spin │ │ ├── index.js │ │ ├── demo.js │ │ └── spin.less │ ├── nav.js │ ├── Verify │ │ ├── demo.js │ │ ├── verify.less │ │ └── index.js │ ├── Dialog │ │ ├── showMsg.js │ │ ├── index.js │ │ ├── demo.js │ │ ├── modal.less │ │ └── modal.js │ ├── data.js │ ├── hello.js │ ├── app.js │ └── app.less ├── main.js └── index.tpl.html ├── docs ├── vendor-49974.min.js ├── index.html └── bundle-49974.min.css ├── README.md ├── .eslintrc ├── server.js ├── webpack.config.js ├── package.json ├── webpack.production.config.js └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build/ 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0", "react"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | dependent 4 | coverage 5 | webpack.*.js 6 | *Server.js 7 | -------------------------------------------------------------------------------- /src/component/use/listLoading: -------------------------------------------------------------------------------- 1 | import ListLoading from ListLoading 2 | 3 | ... 4 | //无参数,直接调用即可 5 | ... -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom' 3 | import App from './component/app.js' 4 | 5 | ReactDOM.render(, document.getElementById('root')); 6 | -------------------------------------------------------------------------------- /docs/vendor-49974.min.js: -------------------------------------------------------------------------------- 1 | !function(r){function e(t){if(o[t])return o[t].exports;var n=o[t]={exports:{},id:t,loaded:!1};return r[t].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var o={};e.m=r,e.c=o,e.p="./"}([]); -------------------------------------------------------------------------------- /src/component/use/useRollNotice.de: -------------------------------------------------------------------------------- 1 | import RollNotice from 'RollNotice' 2 | 3 | ... 4 | const data = [ 5 | '手机尾号1234的用户获得三等奖', 6 | '手机尾号7788的用户获得三等奖', 7 | '手机尾号3428的用户获得四等奖' 8 | ] 9 | return ( 10 | 14 | ) 15 | ... 16 | 17 | -------------------------------------------------------------------------------- /src/component/ListLoading/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import style from './listloading.less'; 3 | 4 | const ListLoading = () => ( 5 |
6 |
加载中...
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | ) 16 | 17 | export default ListLoading 18 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ActiUI 2 | 基于 React 的前端组件库,提供一些常用组件库里不常见的组件与功能,具体使用详情请查看 [https://tumars.github.io/ActiUI/](https://tumars.github.io/ActiUI/) 3 | 4 | ## 补充说明 5 | 这份组件库是刚学习 react 时写的,代码质量稀烂。。。。 6 | 7 | 由于 up 主业务缠身,太忙(懒),这份代码已经一年多未更新,年久失修,文件结构、代码规范、实现方式、语法逻辑等等都已比较落后。各位看看理念就好。up 主日后会抽时重新整理更新。 8 | 9 | 这份 https://github.com/tumars/boilerplate-webpack-react-es6-cssModule 使用了类似的理念与框架,代码相对较新。各位看官请参考这份。 10 | 11 | 谢谢。 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/component/RollNotice/demo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import RollNotice from '../RollNotice' 3 | 4 | const useRollNotice = () => { 5 | const data = [ 6 | '手机尾号1234的用户获得三等奖', 7 | '手机尾号7788的用户获得三等奖', 8 | '手机尾号3428的用户获得四等奖' 9 | ] 10 | return ( 11 |
12 | 16 |
17 | 21 |
22 | ) 23 | } 24 | 25 | export default useRollNotice -------------------------------------------------------------------------------- /src/component/use/useTabSwitch.de: -------------------------------------------------------------------------------- 1 | import TabSwitch from 'TabSwitch' 2 | 3 | ... 4 | const c1 = (
我的标签一的内容
) 5 | const c2 = (
我的标签二的内容
) 6 | const c3 = (
我的标签三的内容
) 7 | 8 | const panels = [ 9 | {title: '列表一', content: c1}, 10 | {title: '列表二', content: c2}, 11 | {title: '列表三', content: c3} 12 | ] 13 | return ( 14 |
15 | console.log(`上一页是${prev},下一页是${now}`)} 19 | /> 20 |
21 | ) 22 | ... -------------------------------------------------------------------------------- /src/component/TabSwitch/demo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import TabSwitch from '../TabSwitch' 3 | 4 | const useTabSwitch = () => { 5 | const c1 = (
我的标签一的内容
) 6 | const c2 = (
我的标签二的内容
) 7 | const c3 = (
我的标签三的内容
) 8 | 9 | const panels = [ 10 | {title: '列表一', content: c1}, 11 | {title: '列表二', content: c2}, 12 | {title: '列表三', content: c3} 13 | ] 14 | return ( 15 |
16 | console.log(`上一页是${prev},下一页是${now}`)} 20 | /> 21 |
22 | ) 23 | } 24 | 25 | export default useTabSwitch -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "jsx": true, 4 | "es6": true, 5 | "modules": true 6 | }, 7 | "env": { 8 | "browser": true, 9 | "node": true, 10 | "mocha": true 11 | }, 12 | "parser": "babel-eslint", 13 | "rules": { 14 | no-empty: ["error", { "allowEmptyCatch": true }], 15 | "strict": [2, "never"], 16 | "react/jsx-uses-react": "error", 17 | "react/jsx-uses-vars": "error", 18 | "no-console": ["error", { allow: ["warn", "error", "log", "info"] }] 19 | }, 20 | "Options": "except-parens", 21 | "plugins": [ 22 | "react" 23 | ], 24 | "extends": ["eslint:recommended", "plugin:react/recommended"] 25 | } 26 | 27 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var WebpackDevServer = require('webpack-dev-server'); 3 | var config = require('./webpack.config'); 4 | 5 | const isDeveloping = process.env.NODE_ENV !== 'production'; 6 | const port = isDeveloping ? 3000 : process.env.PORT; 7 | 8 | var compiler = webpack(config); 9 | var server = new WebpackDevServer(compiler, { 10 | publicPath: config.output.publicPath, 11 | hot: true, 12 | historyApiFallback: true, 13 | stats: { 14 | colors: true, 15 | hash: false, 16 | timings: true, 17 | chunks: false, 18 | chunkModules: false, 19 | modules: false 20 | } 21 | }); 22 | 23 | server.listen(3000, 'localhost', function(err, result) { 24 | if (err) { 25 | return console.log(err); 26 | } 27 | console.log('Listening at http://localhost:3000/'); 28 | }); -------------------------------------------------------------------------------- /src/component/use/useMarquee.de: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import Marquee from '../Marquee' 3 | 4 | class UseMarquee extends Component { 5 | constructor(props) { 6 | super(props) 7 | this.state ={ 8 | prize: -1, 9 | startGame: false 10 | } 11 | } 12 | handleMarqueeStart() { 13 | //获取用户数据,开始游戏,改变 prize 值 14 | this.setState({ 15 | startGame: true, 16 | prize: 6 17 | }) 18 | } 19 | handleMarqueeResult() { 20 | //结束游戏,弹框提示获奖 21 | alert('恭喜你获得奖励'+this.state.prize) 22 | } 23 | render() { 24 | return ( 25 | this.handleMarqueeStart()} 29 | onResult={() => this.handleMarqueeResult()} 30 | /> 31 | ) 32 | } 33 | } 34 | 35 | export default UseMarquee -------------------------------------------------------------------------------- /src/component/Marquee/demo.js: -------------------------------------------------------------------------------- 1 | import React, { Component }from 'react' 2 | import Marquee from '../Marquee' 3 | 4 | class UseMarquee extends Component { 5 | 6 | constructor(props) { 7 | super(props) 8 | this.state ={ 9 | prize: -1, 10 | startGame: false 11 | } 12 | } 13 | handleMarqueeStart() { 14 | //获取用户数据,开始游戏,改变 prize 值 15 | this.setState({ 16 | startGame: true, 17 | prize: 6 18 | }) 19 | 20 | } 21 | handleMarqueeResult() { 22 | //结束游戏,弹框提示获奖 23 | alert('恭喜你获得奖励'+this.state.prize) 24 | } 25 | render() { 26 | return ( 27 | this.handleMarqueeStart()} 31 | onResult={() => this.handleMarqueeResult()} 32 | /> 33 | ) 34 | } 35 | } 36 | 37 | 38 | export default UseMarquee -------------------------------------------------------------------------------- /src/component/RollNotice/notice.less: -------------------------------------------------------------------------------- 1 | .content { 2 | display: table; 3 | width: 100%; 4 | overflow-y: hidden; 5 | line-height: 20px; 6 | } 7 | .icon { 8 | display: table-cell; 9 | width: 20px; 10 | height: 20px; 11 | } 12 | .box { 13 | position: relative; 14 | display: table-cell; 15 | overflow-y: hidden; 16 | width: 100%; 17 | } 18 | .inner { 19 | display: block; 20 | position: absolute; 21 | left: 5px; 22 | } 23 | 24 | 25 | 26 | 27 | .enter { 28 | transform: translate(0, 100%); 29 | opacity: 0.01; 30 | } 31 | .enterActive { 32 | transform: translate(0, 0); 33 | opacity: 1; 34 | transition: all 300ms ease-in; 35 | } 36 | 37 | .leave { 38 | transform: translate(0, 0); 39 | opacity: 1; 40 | } 41 | 42 | .leaveActive { 43 | transform: translate(0, -100%); 44 | opacity: 0.01; 45 | transition: all 300ms ease-in; 46 | } 47 | -------------------------------------------------------------------------------- /src/component/Spin/index.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import style from './spin.less'; 3 | 4 | 5 | const spin = ({blur, isFixed}) => ( 6 |
7 | {blur == null ? null : 8 |
{blur}
9 | } 10 | {!isFixed ? null: 11 |
12 | } 13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | ) 25 | 26 | spin.propTypes = { 27 | isFixed: PropTypes.bool, 28 | blur: PropTypes.node 29 | } 30 | 31 | spin.defaultProps = { 32 | isFixed: false, 33 | blur: null 34 | } 35 | 36 | export default spin 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/component/use/useSpin.de: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Spin from '../Spin' 3 | 4 | const bg = ( 5 |
6 |

我是要被虚化的标题

7 |

我是要被虚化的内容,我是要被虚化的内容

8 |
9 | ) 10 | 11 | const UseSpin = () => ( 12 |
13 |
14 | 15 | {bg} 16 |
17 |
18 |
19 | 20 |
21 |
22 | 23 | ) 24 | 25 | export default UseSpin 26 | 27 | --------------------------------- 28 | 29 | .content { 30 | position: relative; 31 | width: 260px; 32 | box-sizing: border-box 33 | } 34 | .btn { 35 | width: 150px; 36 | height: 30px; 37 | line-height: 30px; 38 | text-align: center; 39 | color: #fff; 40 | background: #108ee9; 41 | border-radius: 4px 42 | } 43 | .bg { 44 | box-sizing: border-box; 45 | padding: 10px; 46 | border: solid 1px #e9e9e9 47 | } 48 | -------------------------------------------------------------------------------- /src/component/Spin/demo.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Spin from '../Spin' 3 | 4 | const style = { 5 | content: { 6 | position: 'relative', 7 | width: '260px', 8 | boxSizing: 'border-box' 9 | }, 10 | btn: { 11 | width: '150px', 12 | height: '30px', 13 | lineHeight: '30px', 14 | textAlign: 'center', 15 | color: '#fff', 16 | background: '#108ee9', 17 | borderRadius: '4px' 18 | }, 19 | bg: { 20 | boxSizing: 'border-box', 21 | padding: '10px', 22 | border: 'solid 1px #e9e9e9' 23 | } 24 | } 25 | 26 | const bg = ( 27 |
28 |

我是要被虚化的标题

29 |

我是要被虚化的内容,我是要被虚化的内容

30 |
31 | ) 32 | 33 | const UseSpin = () => ( 34 |
35 |
36 | 37 | {bg} 38 |
39 |
40 |
41 | 42 |
43 |
44 | 45 | ) 46 | 47 | export default UseSpin -------------------------------------------------------------------------------- /src/component/nav.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { hashHistory } from 'react-router' 3 | import data from '../component/data.js' 4 | 5 | import style from './app.less' 6 | 7 | const arr = Object.keys(data) 8 | class Nav extends Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = { 12 | i: -1 13 | } 14 | } 15 | handleClick(i, id) { 16 | this.setState({ 17 | i: i 18 | }) 19 | hashHistory.replace(id) 20 | } 21 | render() { 22 | return ( 23 |
    24 |
  • this.handleClick(-1, '/')}>简介
  • 25 | { 26 | arr.map((val, index)=> 27 |
  • this.handleClick(index, data[val].id)}> 28 | 29 | {data[val].name}{data[val].id} 30 | 31 |
  • 32 | ) 33 | } 34 |
35 | ) 36 | } 37 | } 38 | 39 | export default Nav -------------------------------------------------------------------------------- /src/component/Verify/demo.js: -------------------------------------------------------------------------------- 1 | import React, { Component }from 'react' 2 | import Verify from "../Verify"; 3 | 4 | class UseVerify extends Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = { 8 | isShowV: false, 9 | verifyTip: null 10 | } 11 | } 12 | 13 | setTip(text) { 14 | this.setState({verifyTip: text}) 15 | } 16 | 17 | handleSendSms(mobile) { 18 | alert(`手机号:${mobile}`) 19 | setTimeout(()=> 20 | this.setTip('已发送,请注意查收') 21 | ,3000) 22 | 23 | } 24 | 25 | handleComfirm(mobile, valid) { 26 | alert(`手机:${mobile},验证码:${valid}`) 27 | setTimeout(()=> 28 | this.setTip('验证码已过期,请重新发送') 29 | ,3000) 30 | } 31 | 32 | render() { 33 | const { verifyTip } = this.state 34 | return ( 35 |
36 | this.handleSendSms(mobile)} 39 | onConfirm={(mobile, valid)=>this.handleComfirm(mobile, valid)} 40 | /> 41 |
42 | ) 43 | } 44 | } 45 | 46 | export default UseVerify -------------------------------------------------------------------------------- /src/component/use/useVerify.de: -------------------------------------------------------------------------------- 1 | import React, { Component }from 'react' 2 | import Verify from "../Verify"; 3 | 4 | class UseVerify extends Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = { 8 | isShowV: false, 9 | verifyTip: null 10 | } 11 | } 12 | 13 | setTip(text) { 14 | this.setState({verifyTip: text}) 15 | } 16 | 17 | handleSendSms(mobile) { 18 | alert(`手机号:${mobile}`) 19 | setTimeout(()=> 20 | this.setTip('已发送,请注意查收') 21 | ,3000) 22 | 23 | } 24 | 25 | handleComfirm(mobile, valid) { 26 | alert(`手机:${mobile},验证码:${valid}`) 27 | setTimeout(()=> 28 | this.setTip('验证码已过期,请重新发送') 29 | ,3000) 30 | } 31 | 32 | render() { 33 | const { verifyTip } = this.state 34 | return ( 35 |
36 | this.handleSendSms(mobile)} 39 | onConfirm={(mobile, valid)=>this.handleComfirm(mobile, valid)} 40 | /> 41 |
42 | ) 43 | } 44 | } 45 | 46 | export default UseVerify -------------------------------------------------------------------------------- /src/component/Dialog/showMsg.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import ReactDOM from 'react-dom' 3 | import Modal from './modal' 4 | 5 | let that = null 6 | const container = document.createElement('div') 7 | document.body.appendChild(container) 8 | 9 | class ShowM extends Component{ 10 | constructor(props) { 11 | super(props) 12 | this.state = { 13 | show: false, 14 | content: '' 15 | } 16 | that = this 17 | } 18 | 19 | componentWillUnmount() { 20 | document.removeChild(container) 21 | } 22 | 23 | render() { 24 | return( 25 | 28 |
{this.state.content}
29 |
30 | ) 31 | } 32 | } 33 | 34 | ReactDOM.render(, container) 35 | 36 | 37 | export default function showMsg (msg) { 38 | that.setState({ 39 | show: true, 40 | content: msg 41 | }) 42 | } -------------------------------------------------------------------------------- /src/component/use/useDialog.de: -------------------------------------------------------------------------------- 1 | import React, { Component }from 'react' 2 | import Dialog from '../Dialog' 3 | 4 | class UseDialog extends Component { 5 | constructor(props) { 6 | super(props) 7 | this.state ={showdiaolg: false} 8 | this.handleClose = this.handleClose.bind(this) 9 | this.handleClick = this.handleClick.bind(this) 10 | } 11 | handleClose() { 12 | this.setState({showdiaolg: false}) 13 | console.log('弹框关闭') 14 | } 15 | handleClick() { 16 | this.setState({showdiaolg: true}) 17 | } 18 | handleClickS() { 19 | Dialog.showMsg('HEY, 我是弹框的内容') 20 | } 21 | render() { 22 | const state = this.state 23 | const pop = ( 24 | 28 |

我是弹框

29 |

我是弹框的内容

30 |
31 | ) 32 | return ( 33 |
34 | {pop} 35 |
第一种调用方式
36 |
第二种调用方式
37 |
38 | ) 39 | } 40 | } 41 | 42 | export default UseDialog -------------------------------------------------------------------------------- /src/component/Dialog/index.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes,Component } from 'react' 2 | import ReactDOM from 'react-dom' 3 | import Modal from './modal' 4 | import showMsg from "./showMsg"; 5 | 6 | class Dialog extends Component { 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | renderPoral() { 12 | ReactDOM.unstable_renderSubtreeIntoContainer( 13 | this, 14 | 15 | {this.props.children} 16 | , 17 | this.node 18 | ) 19 | } 20 | 21 | componentDidMount() { 22 | this.node = document.createElement('div') 23 | document.body.appendChild(this.node) 24 | this.renderPoral() 25 | } 26 | 27 | componentDidUpdate() { 28 | this.renderPoral() 29 | } 30 | 31 | componentWillUnmount() { 32 | document.body.removeChild(this.node) 33 | } 34 | 35 | render() { 36 | return null 37 | } 38 | } 39 | 40 | Dialog.propTypes = { 41 | onClose: PropTypes.func, 42 | visible: PropTypes.bool, 43 | children:PropTypes.node 44 | }; 45 | 46 | Dialog.defaultProps = { 47 | visible: false 48 | }; 49 | 50 | 51 | Dialog.showMsg = showMsg 52 | export default Dialog -------------------------------------------------------------------------------- /src/component/Marquee/marquee.less: -------------------------------------------------------------------------------- 1 | 2 | .content { 3 | position: relative; 4 | } 5 | .box { 6 | position: relative; 7 | background: #eee; 8 | background-size: 100%; 9 | width: 302px; 10 | height: 302px; 11 | text-align: center; 12 | margin: 0 auto; 13 | li { 14 | position: absolute; 15 | display: block; 16 | width: 75px; 17 | height: 75px; 18 | line-height: 75px; 19 | border: solid 1px #898989; 20 | &:nth-child(1) {top:22px;left: 22px;} 21 | &:nth-child(2) {top:22px;left: 110px;} 22 | &:nth-child(3) {top:22px;left: 197px;} 23 | &:nth-child(4) {top:110px;left: 197px;} 24 | &:nth-child(5) {top:197px;left: 197px;} 25 | &:nth-child(6) {top:197px;left: 110px;} 26 | &:nth-child(7) {top:197px;left: 22px;} 27 | &:nth-child(8) {top:110px;left: 22px;} 28 | } 29 | } 30 | .active { 31 | border: solid 4px #ffd700; 32 | box-shadow: 3px 3px 0 #ffd700 inset, 33 | -3px -3px 0 #ffd700 inset; 34 | } 35 | 36 | .start { 37 | position: absolute; 38 | width: 75px; 39 | height: 75px; 40 | line-height: 75px; 41 | top: 110px; 42 | left: 110px; 43 | border: solid 1px #898989; 44 | } 45 | .start_disable { 46 | .start; 47 | border: solid 1px #ccc; 48 | color: #ccc; 49 | } 50 | -------------------------------------------------------------------------------- /src/component/TabSwitch/tabswitch.less: -------------------------------------------------------------------------------- 1 | .content { 2 | width: 100%; 3 | margin: 0 auto; 4 | font-size: 14px; 5 | } 6 | .head { 7 | width: 100%; 8 | display: flex; 9 | justify-content: space-between; 10 | align-items: flex-end; 11 | li { 12 | width: 48.5%; 13 | text-align: center; 14 | height: 30px; 15 | line-height: 30px; 16 | color: #fff; 17 | font-size: 1.2em; 18 | font-weight: bold; 19 | background: #dd514c; 20 | border: 1px solid #d9d9d9; 21 | border-bottom: none; 22 | border-radius: .5em .5em 0 0; 23 | } 24 | } 25 | li.active { 26 | position: relative; 27 | height: 40px; 28 | line-height: 40px; 29 | font-size: 1.2em; 30 | color: #898989; 31 | background: #fff; 32 | 33 | &:after { 34 | content: ''; 35 | position: absolute; 36 | z-index: 1; 37 | bottom: -2px; 38 | left: 0; 39 | width: 100%; 40 | border-top: solid 4px #fff; 41 | background: #fff; 42 | } 43 | } 44 | 45 | .body { 46 | position: relative; 47 | box-sizing: border-box; 48 | min-height: 150px; 49 | border: 1px solid #d9d9d9; 50 | text-align: center; 51 | } 52 | .box{ 53 | position: absolute; 54 | width: 100%; 55 | } 56 | 57 | 58 | .enter { 59 | opacity: 0.5; 60 | } 61 | .enterActive { 62 | opacity: 1; 63 | transition: all 150ms ease-in; 64 | } 65 | 66 | .leave { 67 | opacity: .5; 68 | } 69 | 70 | .leaveActive { 71 | opacity: 0.01; 72 | transition: all 150ms ease-in; 73 | } -------------------------------------------------------------------------------- /src/component/Dialog/demo.js: -------------------------------------------------------------------------------- 1 | import React, { Component }from 'react' 2 | import Dialog from '../Dialog' 3 | 4 | const style = { 5 | box: { 6 | boxSizing: 'border-box', 7 | padding: '20px', 8 | color: 'rgb(16, 142, 233)' 9 | }, 10 | btn: { 11 | width: '150px', 12 | height: '30px', 13 | lineHeight: '30px', 14 | margin: '20px 0', 15 | textAlign: 'center', 16 | color: '#fff', 17 | background: '#108ee9', 18 | borderRadius: '4px' 19 | } 20 | } 21 | 22 | 23 | class UseDialog extends Component { 24 | 25 | constructor(props) { 26 | super(props) 27 | this.state ={ 28 | showdiaolg: false 29 | } 30 | this.handleClose = this.handleClose.bind(this) 31 | this.handleClick = this.handleClick.bind(this) 32 | this.handleClickS = this.handleClickS.bind(this) 33 | } 34 | handleClose() { 35 | this.setState({ 36 | showdiaolg: false 37 | }) 38 | 39 | console.log('弹框关闭') 40 | } 41 | handleClick() { 42 | this.setState({ 43 | showdiaolg: true 44 | }) 45 | } 46 | handleClickS() { 47 | Dialog.showMsg('HEY, 我是弹框的内容') 48 | } 49 | render() { 50 | const state = this.state 51 | const pop = ( 52 | 56 |
57 |

我是弹框

58 |

我是弹框的内容

59 |
60 |
61 | ) 62 | return ( 63 |
64 | {pop} 65 |
第一种调用方式
66 |
第二种调用方式
67 |
68 | 69 | ) 70 | } 71 | } 72 | 73 | export default UseDialog -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | var autoprefixer = require('autoprefixer'); 5 | 6 | 7 | module.exports = { 8 | devtool: 'eval', 9 | entry: [ 10 | 'webpack-dev-server/client?http://localhost:3000', 11 | 'webpack/hot/only-dev-server', 12 | './src/main' 13 | ], 14 | output: { 15 | path: path.join(__dirname, '/dist/'), 16 | filename: 'bundle.js', 17 | publicPath: '/static/' 18 | }, 19 | plugins: [ 20 | new webpack.optimize.OccurenceOrderPlugin(), 21 | new webpack.HotModuleReplacementPlugin(), 22 | new webpack.NoErrorsPlugin() 23 | ], 24 | module: { 25 | preLoaders: [ 26 | {test: /\.js$/, loader: "eslint-loader", exclude: /node_modules/} 27 | ], 28 | loaders: [{ 29 | test: /\.js$/, 30 | loaders: ['react-hot', 'babel'], 31 | include: path.join(__dirname, 'src') 32 | }, { 33 | test: /\.less$/, 34 | exclude: [/node_modules/], 35 | loader: 'style!css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]!resolve-url!less' 36 | }, { 37 | test: /\.css$/, 38 | exclude: [/node_modules/], 39 | loader: 'style!css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]' 40 | }, { 41 | test:/\.(png|jpg)$/, 42 | exclude: [/node_modules/], 43 | loader: 'url?limit=5120&name=build/[name].[ext]' 44 | }] 45 | }, 46 | postcss: [ autoprefixer({ browsers: ['last 2 versions'] }) ], 47 | eslint: { failOnWarning: true }, 48 | resolve: { 49 | extensions: ['', '.js', '.jsx', '.json'] 50 | } 51 | }; -------------------------------------------------------------------------------- /src/component/ListLoading/listloading.less: -------------------------------------------------------------------------------- 1 | .content { 2 | position: relative; 3 | } 4 | .errtip { 5 | position: relative; 6 | // filter: blur(2px); 7 | // filter: ~"progid\:DXImageTransform\.Microsoft\.Blur(PixelRadius\=1, MakeShadow\=false)"; /* IE6~IE9 */ 8 | div { 9 | position: relative; 10 | display: block; 11 | height: 7px; 12 | margin: 0 0 13px; 13 | background: #ddd; 14 | 15 | &::before { 16 | content: ""; 17 | opacity: 0; 18 | position: absolute; 19 | top: 0; 20 | left: 0; 21 | right: 0; 22 | bottom: 0; 23 | background: #eee; 24 | animation: progressactive 1s infinite ease-in-out; 25 | } 26 | 27 | &:nth-child(1) {width: 30%; animation: ball-spin .5s .1s infinite ease-in-out;} 28 | &:nth-child(2) {width: 20%; animation: ball-spin .5s .3s infinite ease-in-out;margin-bottom: 20px;} 29 | &:nth-child(3) {width: 60%; animation: ball-spin .5s .3s infinite ease-in-out;} 30 | &:nth-child(4) {width: 80%; animation: ball-spin .5s .1s infinite ease-in-out;} 31 | &:nth-child(5) {width: 50%; animation: ball-spin .5s .1s infinite ease-in-out;} 32 | } 33 | } 34 | .word { 35 | position: absolute; 36 | top: 0; 37 | right: 0; 38 | color: #333; 39 | font-size: 13px; 40 | font-weight: bold; 41 | animation: fadein .8s infinite; 42 | } 43 | 44 | 45 | @keyframes fadein { 46 | 0%{ 47 | opacity: 1; 48 | } 49 | 50% { 50 | opacity: .7; 51 | } 52 | 100% { 53 | opacity: 1; 54 | } 55 | } 56 | 57 | @keyframes progressactive { 58 | 0% { 59 | opacity: 0.8; 60 | width: 0; 61 | } 62 | 100% { 63 | opacity: 0; 64 | width: 100%; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tumars", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "lint": "eslint src", 9 | "build-mac": "webpack -p --config ./webpack.production.config.js --progress --profile --colors", 10 | "build-win": "del docs && set NODE_ENV=production && webpack -p --config ./webpack.production.config.js --progress --profile --colors" 11 | }, 12 | "author": "tumars", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "autoprefixer": "6.3.6", 16 | "babel-core": "^6.8.0", 17 | "babel-eslint": "^6.0.4", 18 | "babel-loader": "^6.2.4", 19 | "babel-preset-es2015": "^6.6.0", 20 | "babel-preset-react": "^6.5.0", 21 | "babel-preset-react-hmre": "^1.1.1", 22 | "babel-preset-stage-0": "^6.5.0", 23 | "css-loader": "^0.23.1", 24 | "eslint": "^2.9.0", 25 | "eslint-loader": "^1.5.0", 26 | "eslint-plugin-react": "^5.0.1", 27 | "eventsource-polyfill": "^0.9.6", 28 | "exports-loader": "^0.6.3", 29 | "expose-loader": "^0.7.1", 30 | "express": "^4.14.0", 31 | "extract-text-webpack-plugin": "^1.0.1", 32 | "file-loader": "^0.9.0", 33 | "html-webpack-plugin": "^2.17.0", 34 | "imports-loader": "^0.6.5", 35 | "less": "^2.6.1", 36 | "less-loader": "^2.2.3", 37 | "postcss-loader": "^0.9.1", 38 | "raw-loader": "^0.5.1", 39 | "react": "^15.3.0", 40 | "react-dom": "^15.3.0", 41 | "react-hot-loader": "^1.3.0", 42 | "react-syntax-highlighter": "^3.0.0", 43 | "resolve-url-loader": "^1.6.0", 44 | "style-loader": "^0.13.1", 45 | "url-loader": "^0.5.7", 46 | "webpack": "^1.13.0", 47 | "webpack-dev-middleware": "^1.6.1", 48 | "webpack-dev-server": "^1.14.1" 49 | }, 50 | "dependencies": { 51 | "react": "15.3.0", 52 | "react-addons-css-transition-group": "15.3.0", 53 | "react-dom": "15.3.0", 54 | "react-router": "^3.0.0" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/component/Dialog/modal.less: -------------------------------------------------------------------------------- 1 | :global { 2 | /* 背景 */ 3 | #root {transition: all 150ms ease-in;} 4 | .blur-set { 5 | filter: blur(8px); 6 | transform: scale(.98); 7 | } 8 | } 9 | 10 | .dyy { 11 | position: fixed; 12 | z-index: 10; 13 | top: 0; 14 | left: 0; 15 | box-sizing: border-box; 16 | width: 100%; 17 | height: 100%; 18 | background: rgba(0, 0, 0, 0.3); 19 | } 20 | 21 | .default { 22 | z-index: 20; 23 | position: fixed; 24 | top: 70px; 25 | left: 50%; 26 | right: 0; 27 | box-sizing: border-box; 28 | width: 310px; 29 | margin-left: -155px; 30 | font-size: 16px; 31 | line-height: 1.5; 32 | background: #fff; 33 | border-radius: 12px; 34 | } 35 | 36 | .close { 37 | position: absolute; 38 | z-index: 30; 39 | right: 0; 40 | top: 0; 41 | width: 32px; 42 | height: 32px; 43 | line-height: 40px; 44 | font-size: 16px; 45 | font-weight: bold; 46 | border-radius: 0 12px 0 0; 47 | text-align: center; 48 | overflow: hidden; 49 | 50 | svg { 51 | width: 20px; 52 | height: 20px; 53 | fill: #999; 54 | } 55 | } 56 | 57 | 58 | /* 动画 */ 59 | .fadeEnter { 60 | opacity: 0.01; 61 | } 62 | .fadeEnterActive { 63 | opacity: 1; 64 | transition: opacity 200ms linear; 65 | } 66 | .fadeLeave { 67 | opacity: 1; 68 | } 69 | .fadeLeaveActive { 70 | opacity: 0.01; 71 | transition: opacity 200ms ease-in; 72 | } 73 | 74 | 75 | .slideEnter { 76 | opacity: 0.01; 77 | transform: scale(.8); 78 | } 79 | .slideEnterActive { 80 | opacity: 1; 81 | transform: scale(1); 82 | transition: transform 100ms linear, opacity 100ms linear; 83 | } 84 | 85 | .slideLeave { 86 | opacity: 1; 87 | transform: translate(0, 0); 88 | } 89 | .slideLeaveActive { 90 | opacity: 0.01; 91 | transform: translate(0, 2rem) scale(.8); 92 | transition: transform 200ms ease-in, opacity 200ms linear; 93 | } -------------------------------------------------------------------------------- /src/component/TabSwitch/index.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes, Component } from 'react'; 2 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group' 3 | import style from './tabswitch.less'; 4 | 5 | class TabSwitch extends Component { 6 | constructor(props) { 7 | super(props) 8 | const activeIndex = this.props.activeIndex 9 | this.state = { 10 | activeIndex 11 | } 12 | } 13 | 14 | handleTabClick(i) { 15 | const { activeIndex } = this.state 16 | i !== activeIndex && this.props.onTabChange && this.props.onTabChange(activeIndex, i) 17 | 18 | this.setState({ 19 | activeIndex: i 20 | }) 21 | } 22 | 23 | render() { 24 | const { panels } = this.props 25 | const box =
{panels[this.state.activeIndex].content}
26 | 27 | return ( 28 |
29 |
    30 | {panels.map((val,i) => 31 |
  • this.handleTabClick(i)}>{val.title}
  • 32 | )} 33 |
34 |
35 | 46 | {box} 47 | 48 |
49 |
50 | ) 51 | } 52 | } 53 | 54 | TabSwitch.propTypes = { 55 | activeIndex: PropTypes.number, 56 | panels: PropTypes.arrayOf(PropTypes.object), 57 | onTabChange: PropTypes.func 58 | } 59 | 60 | TabSwitch.defaultProps = { 61 | activeIndex: 1, 62 | panels: [ 63 | {title: 'tab1',content: 'empty1'}, 64 | {title: 'tab2',content: 'empty2'} 65 | ] 66 | } 67 | 68 | export default TabSwitch -------------------------------------------------------------------------------- /src/component/data.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ListLoading from './ListLoading' 3 | import useTabSwitch from './TabSwitch/demo.js' 4 | import useRollNotice from './RollNotice/demo.js' 5 | import UseMarquee from './Marquee/demo.js' 6 | import UseDialog from './Dialog/demo.js' 7 | import UseSpin from './Spin/demo.js' 8 | import UseVerify from './Verify/demo.js' 9 | 10 | 11 | const data = { 12 | 'Loading': { 13 | id: 'Loading', 14 | name: '带文本框样式的加载', 15 | demo: , 16 | instru: '适用于在卡片列表等元素加载完成前显示,表示列表正在加载中', 17 | code: require("raw-loader!./use/listLoading"), 18 | api: null 19 | }, 20 | 'TabSwitch': { 21 | id:'TabSwitch', 22 | name: '标签切换', 23 | demo: useTabSwitch(), 24 | instru: '多标签页切换,可渲染两个及以上标签页,接收每个标签页的标题名与内容', 25 | code: require("raw-loader!./use/useTabSwitch.de"), 26 | api: [ 27 | 'activeIndex|默认显示的标签|number|1', 28 | 'panels|标签页的名字及内容|array,[ReactNode]|[{title: "tab1",content: "empty1"}]', 29 | 'onTabChange|标签切换时的事件|function|null' 30 | ] 31 | }, 32 | 'RollNotice': { 33 | id: 'RollNotice', 34 | name: '滚动公告', 35 | demo: useRollNotice(), 36 | instru: '滚动公告,常用于用户获奖公告', 37 | code: require("raw-loader!./use/useRollNotice.de"), 38 | api: [ 39 | 'data|要滚动显示的数据组|array|null', 40 | 'color|喇叭与文字颜色|string|#000' 41 | ] 42 | }, 43 | 'Marquee': { 44 | id: 'Marquee', 45 | name: '跑马灯抽奖', 46 | demo: , 47 | instru: '用于用户抽奖活动,点击开始执行开始事件,接口获取到奖励后跑马灯开始旋转,定位到奖励后执行结束事件', 48 | code: require("raw-loader!./use/UseMarquee.de"), 49 | api: [ 50 | 'isStart|是否开始游戏|bool|false', 51 | 'prize|获得的奖励位置|number|-1', 52 | 'onStart|点击开始执行的事件|function|()=>alert("网络异常!")', 53 | 'onResult|旋转结束执行的事件|function|()=>alert("网络异常!")' 54 | ] 55 | }, 56 | 'Dialog': { 57 | id: 'Dialog', 58 | name: '弹框', 59 | demo: , 60 | instru: '普通弹框,未设置过多功能,只有个关闭事件。支持使用 Dialog.showMsg(content) 的方式直接调用弹框,content 参数为 string 或 react node。', 61 | code: require("raw-loader!./use/UseDialog.de"), 62 | api: [ 63 | 'onClose|关闭弹窗时执行的事件|function|null', 64 | 'visible|弹框是否可见|bool|fasle' 65 | ] 66 | }, 67 | 'Spin': { 68 | id: 'Spin', 69 | name: '菊花图', 70 | demo: , 71 | instru: '用于表示加载中,可以覆盖组件或整个屏幕,可将需要虚化的内容当做参数传入进行虚化', 72 | code: require("raw-loader!./use/UseSpin.de"), 73 | api: [ 74 | 'isFixed|是否覆盖全屏|bool|false', 75 | 'blur|传入要虚化的内容|ReactNode|null' 76 | ] 77 | }, 78 | 'Verify': { 79 | id: 'Verify', 80 | name: '手机验证', 81 | demo: , 82 | instru: '完整的手机号码验证组件,常配合 Dialog 弹框一块使用', 83 | code: require("raw-loader!./use/UseVerify.de"), 84 | api: [ 85 | 'verifyTip|外部控制的提示|string|null', 86 | 'onSendSms|申请验证码回调事件|function|null', 87 | 'onConfirm|确认回调事件|function|null' 88 | ] 89 | } 90 | } 91 | 92 | export default data 93 | 94 | 95 | -------------------------------------------------------------------------------- /webpack.production.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | var autoprefixer = require('autoprefixer'); 5 | 6 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 7 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 8 | 9 | 10 | 11 | var nodeModulesPath = path.join(__dirname, '/node_modules/'); 12 | 13 | module.exports = { 14 | devtool: false, 15 | entry: { 16 | bundle: './src/main.js' 17 | }, 18 | output: { 19 | path: path.join(__dirname, '/docs/'), 20 | filename: '[name]-[hash:5].min.js', 21 | chunkFilename: '[name]-[hash:5].chunk.js', 22 | publicPath: './' 23 | }, 24 | plugins: [ 25 | new webpack.optimize.CommonsChunkPlugin({ 26 | name: 'vendor', 27 | children: true, 28 | minChunks: 2, 29 | async: true, 30 | }), 31 | new webpack.optimize.OccurenceOrderPlugin(true), 32 | new webpack.optimize.DedupePlugin(), 33 | new webpack.DefinePlugin({ 34 | 'process.env':{ 35 | 'NODE_ENV': JSON.stringify('production') 36 | } 37 | }), 38 | new webpack.optimize.UglifyJsPlugin({ 39 | compress: { 40 | warnings: false 41 | } 42 | }), 43 | new HtmlWebpackPlugin({ 44 | template: 'src/index.tpl.html', 45 | minify: { 46 | removeComments: true, 47 | collapseWhitespace: true, 48 | removeRedundantAttributes: true, 49 | useShortDoctype: true, 50 | removeEmptyAttributes: true, 51 | removeStyleLinkTypeAttributes: true, 52 | keepClosingSlash: true, 53 | minifyJS: true, 54 | minifyCSS: true, 55 | minifyURLs: true, 56 | }, 57 | inject: 'body', 58 | filename: 'index.html' 59 | }), 60 | new ExtractTextPlugin('[name]-[hash:5].min.css'), 61 | ], 62 | module: { 63 | loaders: [{ 64 | test: /\.js$/, 65 | loaders: ['babel'], 66 | include: path.join(__dirname, 'src'), 67 | }, { 68 | test: /\.less$/, 69 | exclude: [/node_modules/], 70 | loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]!resolve-url!postcss!less') 71 | }, { 72 | test: /\.css$/, 73 | exclude: [/node_modules/], 74 | loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]!postcss') 75 | }, { 76 | test:/\.(png|jpg)$/, 77 | exclude: [/node_modules/], 78 | loader: 'url-loader?limit=8192&name=build/[name].[ext]' 79 | }] 80 | }, 81 | resolve: { 82 | extensions: ['', '.js', '.jsx', '.json'] 83 | }, 84 | postcss: [ 85 | require('autoprefixer') 86 | ] 87 | }; -------------------------------------------------------------------------------- /src/component/Verify/verify.less: -------------------------------------------------------------------------------- 1 | .content { 2 | width: 220px; 3 | margin: 0 auto; 4 | padding: 20px 0; 5 | 6 | input { 7 | width: 100%; 8 | height: 44px; 9 | font-size: 16px; 10 | font-weight: bold; 11 | text-align: center; 12 | background-color: #eeeeee; 13 | box-shadow: 2px 2px 0 0 #e5e5e5 inset; 14 | border-radius: 8px; 15 | outline:none 16 | } 17 | } 18 | .validbox { 19 | display: table; 20 | width: 100%; 21 | margin: 10px auto 10px; 22 | } 23 | 24 | 25 | .section:first-child { 26 | display: table-cell; 27 | width: 70%; 28 | overflow: hidden; 29 | 30 | input { 31 | font-size: 16px; 32 | border-radius: 8px 0 0 8px; 33 | } 34 | } 35 | .section:nth-child(2) { 36 | display: table-cell; 37 | width: 30%; 38 | overflow: hidden; 39 | vertical-align: top; 40 | 41 | span { 42 | display: block; 43 | width: 100%; 44 | height: 44px; 45 | line-height: 44px; 46 | font-size: 14px; 47 | color: #fff; 48 | text-align: center; 49 | vertical-align: middle; 50 | border-radius: 0 .4em .4em 0; 51 | background-color: rgb(16, 142, 233); 52 | } 53 | 54 | .time { 55 | color:#fff; 56 | font-size:14px; 57 | background: #ccc; 58 | cursor: not-allowed 59 | } 60 | } 61 | 62 | .btn { 63 | display: block; 64 | margin: 20px auto 0; 65 | line-height: 2; 66 | color: #fff; 67 | font-size: 20px; 68 | font-weight: bold; 69 | text-align: center; 70 | background: rgb(16, 142, 233); 71 | border-radius: 8px; 72 | } 73 | 74 | .tip_show { 75 | display: block; 76 | height: 18px; 77 | color: #710600; 78 | font-size: 12px; 79 | text-align: center; 80 | overflow: hidden; 81 | } 82 | .tip_hide { 83 | .tip_show; 84 | height: 0; 85 | } 86 | 87 | .dotting { 88 | display: inline-block; min-width: 2px; min-height: 2px; 89 | box-shadow: 2px 0 currentColor, 6px 0 currentColor, 10px 0 currentColor; /* for IE9+, ..., 3个点 */ 90 | animation: dot 1.5s infinite step-start both; /* for IE10+, ... */ 91 | } 92 | 93 | .dotting:before { content: '...'; } /* for IE8. 若无需兼容IE8, 此行以及下一行删除*/ 94 | .dotting::before { content: ''; } /* for IE9+ 覆盖 IE8 */ 95 | :root .dotting { margin-right: 8px; } /* for IE9+,FF,CH,OP,SF 占据空间*/ 96 | 97 | @keyframes dot { 98 | 25% { box-shadow: none; } /* 0个点 */ 99 | 50% { box-shadow: 2px 0 currentColor; } /* 1个点 */ 100 | 75% { box-shadow: 2px 0 currentColor, 6px 0 currentColor; /* 2个点 */ } 101 | } 102 | 103 | 104 | .enter { 105 | display: block; 106 | transform: translateY(18px); 107 | opacity: 0.01; 108 | } 109 | .enterActive { 110 | display: block; 111 | transform: translateY(-0); 112 | opacity: 1; 113 | transition: all 150ms ease-in; 114 | } 115 | 116 | .leave { 117 | display: block; 118 | transform: translateY(-0); 119 | opacity: 1; 120 | } 121 | 122 | .leaveActive { 123 | display: block; 124 | transform: translateY(-18px); 125 | opacity: 0.01; 126 | transition: all 150ms ease-in; 127 | } 128 | 129 | -------------------------------------------------------------------------------- /src/component/hello.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import style from './app.less' 3 | 4 | const Hello = () => ( 5 |
6 |
7 |

通知说明:

8 |

这份组件库是刚学习 react 时写的,代码质量稀烂。。。。

9 |

由于 up 主业务缠身,太忙(懒),这份代码已经一年多未更新,年久失修,文件结构、代码规范、实现方式、语法逻辑等等都已比较落后。各位看看理念就好。up 主日后会抽时重新整理更新。

10 |

这份 https://github.com/tumars/boilerplate-webpack-react-es6-cssModule使用了类似的理念与框架,代码相对较新。各位看官请参考这份。

11 |
12 |
13 |

什么是 ActiUI?

14 |

ActiUI 是基于 React 的 web conponent 组件库,包含多个独立的功能性组件,以便前端工程师开发时调取使用。

15 |

ActiUI 目前是个人开发项目,还在不断的完善中,后续会推出更多组件,欢迎各位提 issue 或联系我本人。

16 | 查看源码 17 |
18 |
19 |

ActiUI 的特点?

20 |
    21 |
  • 1.每个组件相互独立解耦,单个组件所需的全部 js、css、jsx 等在同一文件夹内,按需下载使用即可
  • 22 |
  • 2.样式使用 css module + less 书写
  • 23 |
  • 3.使用 webpack 的构建工作流,react + webpack 的构建环境配置请参考:boilerplate-webpack-react-es6-cssModule
  • 24 |
25 |

相对 ant Design、sui、amazeUI 等前端库而言,ActiUI 功能精简,组件分离,冗余代码很少,更容易修改定制。ActiUI 适合有一定 React 基础的前端开发人员。

26 |
27 |
28 |

如何使用?

29 |

ActiUI 暂未提供 npm 安装,使用时直接下载相应文件夹并在 react 项目里引用组件即可。例如 Spin 组件文件路径为 src -> conponent -> Spin,下载该文件夹后在自己的项目中使用 import Spin from 'Spin' 引入即可使用。

30 |

每个组件包含以下三个文件:

31 |
    32 |
  • 1.index.js - 组件主文件,逻辑与界面写在这里
  • 33 |
  • 2.{"{组件名}"}.less - 组件样式文件
  • 34 |
  • 3.demo.js - 组件使用 demo 示例
  • 35 |
36 |
37 |
38 |

您可以通过以下方式联系到我:

39 | 57 |
58 |
59 | ) 60 | 61 | export default Hello -------------------------------------------------------------------------------- /src/component/Dialog/modal.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes, Component } from 'react' 2 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group' 3 | import style from './modal.less'; 4 | 5 | class Modal extends Component { 6 | constructor(props) { 7 | super(props); 8 | 9 | this.state = { 10 | isShow: this.props.visible 11 | }; 12 | } 13 | 14 | componentDidMount() { 15 | if (this.props.visible) { 16 | this.enter(); 17 | } 18 | } 19 | 20 | componentWillReceiveProps(nextProps) { 21 | if (nextProps.visible && !this.state.isShow) { 22 | this.enter() 23 | } else if(!nextProps.visible && this.state.isShow) { 24 | this.leave() 25 | } 26 | } 27 | 28 | componentWillUnmount() { 29 | this.leave(); 30 | } 31 | 32 | changeBgs = { 33 | root: document.getElementById('root'), 34 | change() { 35 | const root = this.root 36 | if (root) { 37 | root.classList.add('blur-set') 38 | } 39 | }, 40 | fix() { 41 | const root = this.root 42 | if (root) { 43 | root.classList.remove('blur-set') 44 | } 45 | } 46 | } 47 | 48 | enter() { 49 | this.setState({ 50 | isShow: true 51 | }) 52 | this.changeBgs.change() 53 | } 54 | 55 | leave() { 56 | this.setState({ 57 | isShow: false 58 | }); 59 | this.changeBgs.fix() 60 | this.props.onClose && this.props.onClose() 61 | } 62 | 63 | render() { 64 | const mask = this.state.isShow ?
this.leave()}>
: null 65 | const InnerContent = this.state.isShow ? ( 66 |
67 |
this.leave()}> 68 | 69 | 70 | 71 |
72 | {this.props.children} 73 |
74 | ) : 75 | null 76 | 77 | return ( 78 |
79 | 90 | {mask} 91 | 92 | 103 | {InnerContent} 104 | 105 |
106 | ); 107 | } 108 | } 109 | 110 | Modal.propTypes = { 111 | onClose: PropTypes.func, 112 | visible: PropTypes.bool, 113 | children:PropTypes.node 114 | }; 115 | 116 | Modal.defaultProps = { 117 | visible: false 118 | }; 119 | 120 | export default Modal; -------------------------------------------------------------------------------- /src/component/RollNotice/index.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes,Component } from 'react'; 2 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group' 3 | import style from './notice.less' 4 | 5 | class RollNotice extends Component { 6 | constructor(props) { 7 | super(props) 8 | this.state = { 9 | word: null 10 | }; 11 | } 12 | componentWillUnmount() { 13 | clearInterval(this.timer) 14 | } 15 | componentDidMount() { 16 | if (this.props.data) { 17 | this.start() 18 | } 19 | } 20 | start() { 21 | const _that = this 22 | _that.setState({ 23 | word: _that.props.data[0] 24 | }) 25 | let i = 0 26 | _that.timer = setInterval(function() { 27 | i == _that.props.data.length-1 ? i = 0 : i++ 28 | _that.setState({ 29 | word: _that.props.data[i] 30 | }) 31 | 32 | }, 4000) 33 | 34 | } 35 | render() { 36 | const inner = ({this.state.word}) 37 | const horn = ( 38 | 39 | 40 | 41 | ) 42 | return ( 43 |
44 | { horn } 45 | 56 | { inner } 57 | 58 |
59 | ); 60 | } 61 | } 62 | 63 | RollNotice.propTypes = { 64 | data: PropTypes.array, 65 | color: PropTypes.string 66 | } 67 | 68 | RollNotice.defaultProps = { 69 | data: ['none'], 70 | color: '#000' 71 | } 72 | 73 | export default RollNotice -------------------------------------------------------------------------------- /src/component/Marquee/index.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes, Component } from 'react' 2 | // import co from '../../methed/Common' 3 | import style from './marquee.less' 4 | 5 | class Marquee extends Component { 6 | constructor(props) { 7 | super(props) 8 | 9 | this.state = { 10 | index:-1, //当前转动到哪个位置,起点位置 11 | count:7, //总共有多少个位置 12 | speed:240, //初始转动速度 13 | times:0, //格子切换次数 14 | cycle:40, //转动基本次数:即至少需要转动多少次再进入抽奖环节 15 | prize:this.props.prize, //中奖位置,默认-1 16 | isScolling:false //是否在旋转中 17 | } 18 | this.roll = this.roll.bind(this) 19 | this.controlRoll = this.controlRoll.bind(this) 20 | this.getResult = this.getResult.bind(this) 21 | } 22 | 23 | componentWillUnmount() { 24 | clearTimeout(this.timer) 25 | } 26 | componentWillReceiveProps(nextProps) { 27 | const _that = this 28 | nextProps.isStart == false ? null : 29 | nextProps.prize == -1 ? null : 30 | nextProps.prize > -1 && nextProps.prize < _that.state.count ? 31 | _that.getResult(nextProps.prize) : alert('网络异常!') 32 | } 33 | roll() { 34 | const _that = this 35 | let i = _that.state.index 36 | let count = _that.state.count 37 | i = i > count - 1 ? 0 : i + 1 38 | _that.setState({index: i}) 39 | } 40 | controlRoll(position) { 41 | const _that = this 42 | _that.setState({times: _that.state.times + 1, isScolling: true}) 43 | _that.roll() 44 | if (_that.state.times > _that.state.cycle+10 && _that.state.prize ==_that.state.index) { 45 | clearTimeout(_that.timer) 46 | _that.setState({ 47 | isScolling: false, 48 | isTiming: false, 49 | prize: -1, 50 | times: 0, 51 | speed: 240 52 | }) 53 | setTimeout(function () { 54 | _that.props.onResult() 55 | },100); 56 | } else { 57 | _that.setState({ 58 | isTiming: true 59 | }) 60 | if(this.state.times < this.state.cycle) { 61 | _that.setState({ speed: this.state.speed - 10}) 62 | } else if (this.state.times == this.state.cycle) { 63 | _that.setState({prize: position}) 64 | } else { 65 | if (_that.state.times > _that.state.cycle+10 && ((_that.state.prize==0 && _that.state.index==7) || _that.state.prize==_that.state.index+1)) { 66 | _that.setState({speed: this.state.speed + 110}) 67 | }else{ 68 | _that.setState({speed: this.state.speed + 20 }) 69 | } 70 | } 71 | if (_that.state.speed<40) { 72 | _that.setState({ 73 | speed: 40 74 | }) 75 | } 76 | _that.timer = setTimeout(function(){ 77 | _that.controlRoll(position) 78 | },_that.state.speed); 79 | } 80 | return false 81 | } 82 | 83 | getResult(position) { 84 | const _that = this 85 | _that.setState({ 86 | isTiming: false 87 | }) 88 | var countInterval = setInterval(function () { 89 | loopQueryRaffleResult(position) 90 | }, 800); 91 | 92 | function loopQueryRaffleResult(position){ 93 | clearInterval(countInterval); 94 | if(_that.state.isTiming == false){ 95 | _that.controlRoll(position); 96 | } 97 | } 98 | } 99 | 100 | 101 | render() { 102 | const { onStart } = this.props 103 | const content = [] 104 | for (var i = 0; i < 8; i++) { 105 | content.push(
  • {i}
  • ) 106 | } 107 | return ( 108 |
    109 |
    110 |
    this.state.isScolling ? false : onStart(e)}>开始
    111 |
      112 | {content} 113 |
    114 |
    115 |
    116 | ) 117 | } 118 | } 119 | 120 | Marquee.propTypes = { 121 | isStart: PropTypes.bool, 122 | prize: PropTypes.number, 123 | onStart: PropTypes.func, 124 | onResult: PropTypes.func 125 | } 126 | 127 | Marquee.defaultProps = { 128 | isStart: false, 129 | prize: -1, 130 | onStart: () => { 131 | alert('网络异常!') 132 | }, 133 | onResult: () => { 134 | alert('网络异常!') 135 | } 136 | } 137 | 138 | export default Marquee -------------------------------------------------------------------------------- /src/component/Verify/index.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes, Component } from 'react' 2 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group' 3 | import style from './verify.less' 4 | 5 | class Verify extends Component { 6 | constructor(props) { 7 | super(props) 8 | this.state = { 9 | isTiming: false, 10 | time: 60, 11 | tip: null 12 | } 13 | } 14 | 15 | componentWillUnmount() { 16 | clearInterval(this.timer) 17 | } 18 | 19 | componentWillReceiveProps(nextProps) { 20 | nextProps.verifyTip && this.setTip(nextProps.verifyTip) 21 | } 22 | 23 | clearTip() { 24 | this.setTip(null) 25 | } 26 | 27 | verifyTel(mobile) { 28 | const reg = /^[1]+[3,4,5,7,8]+\d{9}$/ 29 | return mobile && mobile.length == 11 && reg.test(mobile) 30 | } 31 | 32 | verifyValid(valid) { 33 | const reg = /^\d{4}$/ 34 | return valid && reg.test(valid) 35 | } 36 | 37 | startTime() { 38 | const prop = this.props 39 | 40 | this.setState({ 41 | isTiming: true 42 | }) 43 | 44 | let t = prop.time 45 | this.timer = setInterval(()=>{ 46 | t = t-1 47 | this.setState({ 48 | time: t 49 | }) 50 | 51 | if (t<=0) { 52 | clearInterval(this.timer) 53 | this.setState({ 54 | isTiming: false, 55 | time: this.props.time 56 | }) 57 | } 58 | }, 1000) 59 | } 60 | 61 | setTip(text) { 62 | this.setState({ 63 | tip: text 64 | }) 65 | } 66 | 67 | renderDot() { 68 | return ( 69 | 70 | ) 71 | } 72 | 73 | sendClick() { 74 | const prop = this.props 75 | const mobile = this.refs.PhoneInput.value 76 | 77 | this.clearTip() 78 | 79 | if(!this.verifyTel(mobile)){ 80 | this.setTip('请输入正确手机号') 81 | return 82 | } 83 | this.startTime() 84 | 85 | this.setTip(发送中{this.renderDot()}) 86 | prop.onSendSms(mobile) 87 | } 88 | 89 | confirmClick() { 90 | const prop = this.props 91 | const mobile = this.refs.PhoneInput.value 92 | const valid = this.refs.ValidInput.value 93 | 94 | this.clearTip() 95 | 96 | if(!this.verifyTel(mobile) || !this.verifyValid(valid)){ 97 | this.setTip('请输入正确手机号及验证码') 98 | return 99 | } 100 | 101 | this.setTip(验证中{this.renderDot()}) 102 | prop.onConfirm(mobile, valid) 103 | } 104 | 105 | render() { 106 | return ( 107 |
    108 | this.clearTip()} name="mobile" maxLength="11" placeholder="请输入手机号码" /> 109 |
    110 |
    111 | this.clearTip()} maxLength="4" placeholder="输入验证码" /> 112 |
    113 |
    114 | {this.state.isTiming ? ({this.state.time}s后重试) : ( this.sendClick()}>获取)} 115 |
    116 |
    117 |
    118 | 129 | {this.state.tip} 130 | 131 |
    132 | this.confirmClick()}>确定 133 |
    134 | ) 135 | } 136 | } 137 | 138 | Verify.propTypes = { 139 | verifyTip: PropTypes.string, 140 | time: PropTypes.string, 141 | onSendSms: PropTypes.func.isRequired, 142 | onConfirm: PropTypes.func.isRequired 143 | } 144 | 145 | Verify.defaultProps = { 146 | time: '60', 147 | verifyTip: '' 148 | } 149 | 150 | export default Verify -------------------------------------------------------------------------------- /src/component/app.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import { Router, Route, IndexRoute, hashHistory } from 'react-router' 3 | import SyntaxHighlighter from 'react-syntax-highlighter' 4 | import { arduinoLight } from 'react-syntax-highlighter/dist/styles' 5 | import data from './data.js' 6 | import Nav from './nav.js' 7 | import Hello from './Hello.js' 8 | 9 | import style from './app.less' 10 | 11 | class Card extends Component { 12 | constructor(props) { 13 | super(props); 14 | this.state= { 15 | isShowcode: false 16 | } 17 | } 18 | handleClick() { 19 | this.setState({ 20 | isShowcode: !this.state.isShowcode 21 | }) 22 | } 23 | render() { 24 | const { value } = this.props 25 | const apilist = value.api == null ?

    没有接口,直接使用

    : ( 26 |
    27 |
      28 |
    • 参数
    • 29 |
    • 说明
    • 30 |
    • 类型
    • 31 |
    • 默认值
    • 32 |
    33 | {value.api.map((val,i) => 34 |
      35 |
    • {val.split('|')[0]}
    • 36 |
    • {val.split('|')[1]}
    • 37 |
    • {val.split('|')[2]}
    • 38 |
    • {val.split('|')[3]}
    • 39 |
    40 | )} 41 | 42 |
    43 | ) 44 | return ( 45 |
    46 |
    47 |

    { value.name + ' ' + value.id }

    48 |
    49 |
    50 | { value.demo } 51 |
    52 |
    53 |

    使用说明

    54 |

    { value.instru }

    55 |
    56 |
    57 |

    代码示例

    58 |
    this.handleClick()}> 59 | 60 |
    61 | {this.state.isShowcode ? { value.code } : null} 62 |
    63 |
    64 |

    接口参数

    65 | { apilist } 66 |
    67 | 68 | 69 | 查看该组件源码 70 | 71 |
    72 | 73 |
    74 |
    75 | ) 76 | } 77 | } 78 | 79 | Card.propTypes = { 80 | value: PropTypes.object 81 | } 82 | 83 | Card.defaultProps = { 84 | value: { 85 | name: null, 86 | demo: null, 87 | instru: null, 88 | code: null, 89 | api: null 90 | } 91 | } 92 | 93 | // const wid = document.body.clientWidth 94 | const arr = Object.keys(data) 95 | export default class App extends Component { 96 | constructor(props) { 97 | super(props); 98 | } 99 | 100 | render() { 101 | return ( 102 |
    103 |
    104 |

    Acti UI

    105 |
    106 |
    107 |
    108 |
    110 |
    111 | 112 | 113 | 114 | { 115 | arr.map((val, index)=> 116 | ()} /> 117 | ) 118 | } 119 | 120 | 121 |
    122 |
    123 |
    124 | ); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | ActiUI
    -------------------------------------------------------------------------------- /src/component/Spin/spin.less: -------------------------------------------------------------------------------- 1 | 2 | .content { 3 | width: 100%; 4 | height: inherit; 5 | } 6 | 7 | .dyy { 8 | position: fixed; 9 | z-index: 1; 10 | top: 0; 11 | left: 0; 12 | box-sizing: border-box; 13 | width: 100%; 14 | height: 100%; 15 | background: rgba(225, 225, 225, 0.4); 16 | } 17 | 18 | .blur { 19 | height: inherit; 20 | filter: blur(2px) contrast(.8) brightness(.8); 21 | transform: scale(.98); 22 | } 23 | 24 | .laballspin, 25 | .laballspin > div { 26 | position: absolute; 27 | z-index: 2; 28 | top: 50%; 29 | left: 50%; 30 | transform: translate(-50%, -50%); 31 | -webkit-box-sizing: border-box; 32 | -moz-box-sizing: border-box; 33 | box-sizing: border-box; 34 | } 35 | .laballspin { 36 | display: block; 37 | font-size: 0; 38 | color: #333; 39 | } 40 | .laballspin.la-dark { 41 | color: #333; 42 | } 43 | .laballspin > div { 44 | display: inline-block; 45 | float: none; 46 | background-color: currentColor; 47 | border: 0 solid currentColor; 48 | } 49 | .laballspin { 50 | width: 32px; 51 | height: 32px; 52 | } 53 | .laballspin > div { 54 | position: absolute; 55 | top: 50%; 56 | left: 50%; 57 | width: 8px; 58 | height: 8px; 59 | margin-top: -4px; 60 | margin-left: -4px; 61 | border-radius: 100%; 62 | -webkit-animation: ball-spin 1s infinite ease-in-out; 63 | -moz-animation: ball-spin 1s infinite ease-in-out; 64 | -o-animation: ball-spin 1s infinite ease-in-out; 65 | animation: ball-spin 1s infinite ease-in-out; 66 | } 67 | .laballspin > div:nth-child(1) { 68 | top: 5%; 69 | left: 50%; 70 | -webkit-animation-delay: -1.125s; 71 | -moz-animation-delay: -1.125s; 72 | -o-animation-delay: -1.125s; 73 | animation-delay: -1.125s; 74 | } 75 | .laballspin > div:nth-child(2) { 76 | top: 18.1801948466%; 77 | left: 81.8198051534%; 78 | -webkit-animation-delay: -1.25s; 79 | -moz-animation-delay: -1.25s; 80 | -o-animation-delay: -1.25s; 81 | animation-delay: -1.25s; 82 | } 83 | .laballspin > div:nth-child(3) { 84 | top: 50%; 85 | left: 95%; 86 | -webkit-animation-delay: -1.375s; 87 | -moz-animation-delay: -1.375s; 88 | -o-animation-delay: -1.375s; 89 | animation-delay: -1.375s; 90 | } 91 | .laballspin > div:nth-child(4) { 92 | top: 81.8198051534%; 93 | left: 81.8198051534%; 94 | -webkit-animation-delay: -1.5s; 95 | -moz-animation-delay: -1.5s; 96 | -o-animation-delay: -1.5s; 97 | animation-delay: -1.5s; 98 | } 99 | .laballspin > div:nth-child(5) { 100 | top: 94.9999999966%; 101 | left: 50.0000000005%; 102 | -webkit-animation-delay: -1.625s; 103 | -moz-animation-delay: -1.625s; 104 | -o-animation-delay: -1.625s; 105 | animation-delay: -1.625s; 106 | } 107 | .laballspin > div:nth-child(6) { 108 | top: 81.8198046966%; 109 | left: 18.1801949248%; 110 | -webkit-animation-delay: -1.75s; 111 | -moz-animation-delay: -1.75s; 112 | -o-animation-delay: -1.75s; 113 | animation-delay: -1.75s; 114 | } 115 | .laballspin > div:nth-child(7) { 116 | top: 49.9999750815%; 117 | left: 5.0000051215%; 118 | -webkit-animation-delay: -1.875s; 119 | -moz-animation-delay: -1.875s; 120 | -o-animation-delay: -1.875s; 121 | animation-delay: -1.875s; 122 | } 123 | .laballspin > div:nth-child(8) { 124 | top: 18.179464974%; 125 | left: 18.1803700518%; 126 | -webkit-animation-delay: -2s; 127 | -moz-animation-delay: -2s; 128 | -o-animation-delay: -2s; 129 | animation-delay: -2s; 130 | } 131 | .laballspin.la-sm { 132 | width: 16px; 133 | height: 16px; 134 | } 135 | .laballspin.la-sm > div { 136 | width: 4px; 137 | height: 4px; 138 | margin-top: -2px; 139 | margin-left: -2px; 140 | } 141 | .laballspin.la-2x { 142 | width: 64px; 143 | height: 64px; 144 | } 145 | .laballspin.la-2x > div { 146 | width: 16px; 147 | height: 16px; 148 | margin-top: -8px; 149 | margin-left: -8px; 150 | } 151 | .laballspin.la-3x { 152 | width: 96px; 153 | height: 96px; 154 | } 155 | .laballspin.la-3x > div { 156 | width: 24px; 157 | height: 24px; 158 | margin-top: -12px; 159 | margin-left: -12px; 160 | } 161 | /* 162 | * Animation 163 | */ 164 | @-webkit-keyframes ball-spin { 165 | 0%, 166 | 100% { 167 | opacity: 1; 168 | -webkit-transform: scale(1); 169 | transform: scale(1); 170 | } 171 | 20% { 172 | opacity: 1; 173 | } 174 | 80% { 175 | opacity: 0; 176 | -webkit-transform: scale(0); 177 | transform: scale(0); 178 | } 179 | } 180 | @-moz-keyframes ball-spin { 181 | 0%, 182 | 100% { 183 | opacity: 1; 184 | -moz-transform: scale(1); 185 | transform: scale(1); 186 | } 187 | 20% { 188 | opacity: 1; 189 | } 190 | 80% { 191 | opacity: 0; 192 | -moz-transform: scale(0); 193 | transform: scale(0); 194 | } 195 | } 196 | @-o-keyframes ball-spin { 197 | 0%, 198 | 100% { 199 | opacity: 1; 200 | -o-transform: scale(1); 201 | transform: scale(1); 202 | } 203 | 20% { 204 | opacity: 1; 205 | } 206 | 80% { 207 | opacity: 0; 208 | -o-transform: scale(0); 209 | transform: scale(0); 210 | } 211 | } 212 | @keyframes ball-spin { 213 | 0%, 214 | 100% { 215 | opacity: 1; 216 | -webkit-transform: scale(1); 217 | -moz-transform: scale(1); 218 | -o-transform: scale(1); 219 | transform: scale(1); 220 | } 221 | 20% { 222 | opacity: 1; 223 | } 224 | 80% { 225 | opacity: 0; 226 | -webkit-transform: scale(0); 227 | -moz-transform: scale(0); 228 | -o-transform: scale(0); 229 | transform: scale(0); 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/index.tpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ActiUI 9 | 10 | 11 | 12 | 13 | 87 | 88 | 89 |
    90 |
    91 |
    92 |
    93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ActiUI 9 | 10 | 11 | 12 | 13 | 87 | 88 | 89 |
    90 |
    91 |
    92 |
    93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/component/app.less: -------------------------------------------------------------------------------- 1 | @line:#e9e9e9; 2 | 3 | .content { 4 | box-sizing: border-box; 5 | padding: 0; 6 | line-height: 1.5; 7 | font-family: Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", SimSun, sans-serif; 8 | font-size: 14px; 9 | color: #404040; 10 | .h2 { 11 | margin: 1.6em 0 0.6em 0; 12 | color: #404040; 13 | font-size: 18px; 14 | font-weight: 500; 15 | } 16 | } 17 | body::-webkit-scrollbar {display:none} 18 | pre, code { 19 | font-family: Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", SimSun, sans-serif; 20 | } 21 | .head { 22 | display: block; 23 | width: 100%; 24 | background: #0e90d2; 25 | h1 { 26 | display: block; 27 | width: 960px; 28 | box-sizing: border-box; 29 | margin: 0 auto; 30 | color: #fff; 31 | } 32 | } 33 | 34 | .hello { 35 | box-sizing: border-box; 36 | padding-top: 50px; 37 | section { 38 | margin-bottom: 30px; 39 | } 40 | h2 { 41 | margin: 0 0 0.6em; 42 | color: #404040; 43 | font-size: 18px; 44 | font-weight: 500; 45 | } 46 | p, li { 47 | margin-bottom: 10px; 48 | } 49 | li { 50 | display: table; 51 | width: 100%; 52 | span{ 53 | display: table-cell; 54 | &:first-child { 55 | width: 15px; 56 | } 57 | } 58 | } 59 | 60 | code { 61 | padding: 2px 4px; 62 | color: #c7254e; 63 | background-color: #f8f8f8; 64 | white-space: nowrap; 65 | border-radius: 0; 66 | } 67 | a { 68 | color: #0e90d2; 69 | text-decoration: none; 70 | &:hover {color: #095f8a;} 71 | &:focus {color: #095f8a;} 72 | } 73 | .git { 74 | color: #404040; 75 | text-decoration: none; 76 | &:hover, &:focus{ 77 | color: #404040; 78 | text-decoration: none; 79 | background-color: #ddd; 80 | background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#eee),color-stop(100%,#ddd)); 81 | background-image: linear-gradient(to bottom,#eee 0,#ddd 100%); 82 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#dddddd', GradientType=0); 83 | border-color: #ccc; 84 | } 85 | padding: 3px 10px 3px 8px; 86 | font-size: 16px; 87 | line-height: 22px; 88 | border-radius: 4px; 89 | background-color: #eee; 90 | background-image: linear-gradient(to bottom,#fcfcfc 0,#eee 100%); 91 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fcfcfc', endColorstr='#eeeeee', GradientType=0); 92 | background-repeat: no-repeat; 93 | border: 1px solid #d5d5d5; 94 | 95 | svg { 96 | width: 20px; 97 | height: 20px; 98 | margin-right: 5px; 99 | fill: #404040; 100 | vertical-align: top; 101 | &:hover {color: #095f8a;} 102 | &:focus {color: #095f8a;} 103 | } 104 | } 105 | .contact { 106 | margin-top: 200px; 107 | h4 {line-height: 2.5;} 108 | li { 109 | margin: 10px 0; 110 | overflow: hidden; 111 | text-align: left; 112 | div { 113 | display: inline-block; 114 | &:first-child { 115 | margin-right: 5px; 116 | } 117 | } 118 | } 119 | } 120 | } 121 | 122 | .main{ 123 | display: flex; 124 | width: 1000px; 125 | box-sizing: border-box; 126 | margin: 0 auto; 127 | padding: 20px 20px; 128 | background: #fff; 129 | } 130 | .left_box { 131 | position: relative; 132 | display: block; 133 | width: 100%; 134 | max-width: 200px; 135 | margin: 0 auto; 136 | text-align: left; 137 | } 138 | .right_box { 139 | position: relative; 140 | display: block; 141 | width: 100%; 142 | max-width: 640px; 143 | box-sizing: border-box; 144 | margin: 0px auto; 145 | padding-bottom: 50px; 146 | background: #fff; 147 | overflow: hidden; 148 | } 149 | @media screen and (max-width: 900px) { 150 | .content { 151 | // .content; 152 | .head { 153 | h1 { 154 | width: 100%; 155 | padding: 0 10px; 156 | } 157 | } 158 | .main { 159 | width: 100%; 160 | padding: 10px; 161 | display: block; 162 | flex-direction: column; 163 | justify-content: space-between; 164 | } 165 | .left_box { 166 | margin: 0; 167 | } 168 | .nav { 169 | margin-top: 0; 170 | li { 171 | padding: 0; 172 | } 173 | } 174 | } 175 | } 176 | 177 | .nav { 178 | width: 100%; 179 | margin-top: 50px; 180 | font-size: 14px; 181 | li { 182 | display: block; 183 | box-sizing: border-box; 184 | padding-left: 20px; 185 | line-height: 2.5; 186 | cursor: pointer; 187 | &:hover { 188 | background-color: #e7f4fd; 189 | } 190 | 191 | small { 192 | font-size: .8em; 193 | padding-left: 5px; 194 | } 195 | } 196 | .active { 197 | color: #dd514c; 198 | } 199 | } 200 | 201 | .box { 202 | border: 1px solid @line; 203 | border-radius: 4px; 204 | display: block; 205 | position: relative; 206 | box-sizing: border-box; 207 | margin: 0px auto; 208 | padding-bottom: 10px; 209 | -webkit-transition: all 0.2s ease; 210 | transition: all 0.2s ease; 211 | .git { 212 | display: block; 213 | text-align: right; 214 | box-sizing: border-box; 215 | padding-right: 10px; 216 | color: #0e90d2; 217 | fill: #095f8a; 218 | text-decoration: underline; 219 | &:hover, &:focus {color: #095f8a;fill: #095f8a;} 220 | 221 | svg{ 222 | width: 20px; 223 | height: 20px; 224 | vertical-align: top; 225 | margin-right: 5px; 226 | fill:inherit; 227 | } 228 | } 229 | } 230 | .meta { 231 | position: relative; 232 | border-top: solid 1px @line; 233 | padding: 20px 10px 40px; 234 | font-size: 14px; 235 | h3 { 236 | position: absolute; 237 | top: -12px; 238 | left: 10px; 239 | width: 80px; 240 | font-size: 14px; 241 | text-align: center; 242 | background: #fff; 243 | } 244 | .arrow { 245 | position: absolute; 246 | top: -10px; 247 | right: 10px; 248 | padding: 0 5px; 249 | background: #fff; 250 | svg { 251 | width: 22px; 252 | height: 22px; 253 | cursor: pointer; 254 | transform: rotate(0deg); 255 | transition: all 500ms ease; 256 | &:hover { 257 | fill: #666 258 | } 259 | } 260 | } 261 | .arrow_up { 262 | .arrow; 263 | svg { 264 | transform: rotate(180deg); 265 | // transition: all 500ms ease; 266 | } 267 | } 268 | } 269 | .demo { 270 | width: 100%; 271 | max-width: 320px; 272 | min-height: 100px; 273 | box-sizing: border-box; 274 | padding: 30px 10px 50px; 275 | } 276 | 277 | 278 | .apilist { 279 | ul { 280 | display: table; 281 | width: 100%; 282 | border-left: solid 1px @line; 283 | &:first-child{ 284 | border-top: solid 1px @line; 285 | } 286 | li { 287 | display: table-cell; 288 | width: 25%; 289 | padding: 10px; 290 | border: solid 1px @line; 291 | border-top: none; 292 | border-left: none; 293 | word-wrap: break-word; 294 | word-break:break-all; 295 | } 296 | } 297 | 298 | } -------------------------------------------------------------------------------- /docs/bundle-49974.min.css: -------------------------------------------------------------------------------- 1 | .listloading-content-3pkDB,.listloading-errtip-3Xg8p{position:relative}.listloading-errtip-3Xg8p div{position:relative;display:block;height:7px;margin:0 0 13px;background:#ddd}.listloading-errtip-3Xg8p div:before{content:"";opacity:0;position:absolute;top:0;left:0;right:0;bottom:0;background:#eee;-webkit-animation:listloading-progressactive-1S4Ze 1s infinite ease-in-out;animation:listloading-progressactive-1S4Ze 1s infinite ease-in-out}.listloading-errtip-3Xg8p div:first-child{width:30%;-webkit-animation:listloading-ball-spin-2pAle .5s .1s infinite ease-in-out;animation:listloading-ball-spin-2pAle .5s .1s infinite ease-in-out}.listloading-errtip-3Xg8p div:nth-child(2){width:20%;margin-bottom:20px}.listloading-errtip-3Xg8p div:nth-child(2),.listloading-errtip-3Xg8p div:nth-child(3){-webkit-animation:listloading-ball-spin-2pAle .5s .3s infinite ease-in-out;animation:listloading-ball-spin-2pAle .5s .3s infinite ease-in-out}.listloading-errtip-3Xg8p div:nth-child(3){width:60%}.listloading-errtip-3Xg8p div:nth-child(4){width:80%}.listloading-errtip-3Xg8p div:nth-child(4),.listloading-errtip-3Xg8p div:nth-child(5){-webkit-animation:listloading-ball-spin-2pAle .5s .1s infinite ease-in-out;animation:listloading-ball-spin-2pAle .5s .1s infinite ease-in-out}.listloading-errtip-3Xg8p div:nth-child(5){width:50%}.listloading-word-1XGlg{position:absolute;top:0;right:0;color:#333;font-size:13px;font-weight:700;-webkit-animation:listloading-fadein-138b0 .8s infinite;animation:listloading-fadein-138b0 .8s infinite}@-webkit-keyframes listloading-fadein-138b0{0%{opacity:1}50%{opacity:.7}to{opacity:1}}@keyframes listloading-fadein-138b0{0%{opacity:1}50%{opacity:.7}to{opacity:1}}@-webkit-keyframes listloading-progressactive-1S4Ze{0%{opacity:.8;width:0}to{opacity:0;width:100%}}@keyframes listloading-progressactive-1S4Ze{0%{opacity:.8;width:0}to{opacity:0;width:100%}}.tabswitch-content-WsKYo{width:100%;margin:0 auto;font-size:14px}.tabswitch-head-2ciVr{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.tabswitch-head-2ciVr li{width:48.5%;text-align:center;height:30px;line-height:30px;color:#fff;font-size:1.2em;font-weight:700;background:#dd514c;border:1px solid #d9d9d9;border-bottom:none;border-radius:.5em .5em 0 0}li.tabswitch-active-1ExRQ{position:relative;height:40px;line-height:40px;font-size:1.2em;color:#898989;background:#fff}li.tabswitch-active-1ExRQ:after{content:"";position:absolute;z-index:1;bottom:-2px;left:0;width:100%;border-top:4px solid #fff;background:#fff}.tabswitch-body-UoLsH{position:relative;box-sizing:border-box;min-height:150px;border:1px solid #d9d9d9;text-align:center}.tabswitch-box-24dRP{position:absolute;width:100%}.tabswitch-enter-24SeU{opacity:.5}.tabswitch-enterActive-1kcxR{opacity:1;transition:all .15s ease-in}.tabswitch-leave-2rHGz{opacity:.5}.tabswitch-leaveActive-3xIQ7{opacity:.01;transition:all .15s ease-in}.notice-content-16wAA{display:table;width:100%;overflow-y:hidden;line-height:20px}.notice-icon-3vRQr{display:table-cell;width:20px;height:20px}.notice-box-1hheq{position:relative;display:table-cell;overflow-y:hidden;width:100%}.notice-inner-TupzO{display:block;position:absolute;left:5px}.notice-enter-g089O{-webkit-transform:translateY(100%);transform:translateY(100%);opacity:.01}.notice-enterActive-1LhOP{transition:all .3s ease-in}.notice-enterActive-1LhOP,.notice-leave-30oN7{-webkit-transform:translate(0);transform:translate(0);opacity:1}.notice-leaveActive-NU2-g{-webkit-transform:translateY(-100%);transform:translateY(-100%);opacity:.01;transition:all .3s ease-in}.marquee-content-2MKWD{position:relative}.marquee-box-38jVB{position:relative;background:#eee;background-size:100%;width:302px;height:302px;text-align:center;margin:0 auto}.marquee-box-38jVB li{position:absolute;display:block;width:75px;height:75px;line-height:75px;border:1px solid #898989}.marquee-box-38jVB li:first-child{top:22px;left:22px}.marquee-box-38jVB li:nth-child(2){top:22px;left:110px}.marquee-box-38jVB li:nth-child(3){top:22px;left:197px}.marquee-box-38jVB li:nth-child(4){top:110px;left:197px}.marquee-box-38jVB li:nth-child(5){top:197px;left:197px}.marquee-box-38jVB li:nth-child(6){top:197px;left:110px}.marquee-box-38jVB li:nth-child(7){top:197px;left:22px}.marquee-box-38jVB li:nth-child(8){top:110px;left:22px}.marquee-active-1wwoj{border:4px solid gold;box-shadow:inset 3px 3px 0 gold,inset -3px -3px 0 gold}.marquee-start-2sr-h{border:1px solid #898989}.marquee-start-2sr-h,.marquee-start_disable-3qdhG{position:absolute;width:75px;height:75px;line-height:75px;top:110px;left:110px}.marquee-start_disable-3qdhG{border:1px solid #898989;border:1px solid #ccc;color:#ccc}#root{transition:all .15s ease-in}.blur-set{-webkit-filter:blur(8px);filter:blur(8px);-webkit-transform:scale(.98);transform:scale(.98)}.modal-dyy-1d1qe{position:fixed;z-index:10;top:0;left:0;box-sizing:border-box;width:100%;height:100%;background:rgba(0,0,0,.3)}.modal-default-3gbHo{z-index:20;position:fixed;top:70px;left:50%;right:0;box-sizing:border-box;width:310px;margin-left:-155px;font-size:16px;line-height:1.5;background:#fff;border-radius:12px}.modal-close-oNdsW{position:absolute;z-index:30;right:0;top:0;width:32px;height:32px;line-height:40px;font-size:16px;font-weight:700;border-radius:0 12px 0 0;text-align:center;overflow:hidden}.modal-close-oNdsW svg{width:20px;height:20px;fill:#999}.modal-fadeEnter-1cbT8{opacity:.01}.modal-fadeEnterActive-2ah4b{opacity:1;transition:opacity .2s linear}.modal-fadeLeave-13iph{opacity:1}.modal-fadeLeaveActive-3To8D{opacity:.01;transition:opacity .2s ease-in}.modal-slideEnter-3hhqI{opacity:.01;-webkit-transform:scale(.8);transform:scale(.8)}.modal-slideEnterActive-ae4rr{opacity:1;-webkit-transform:scale(1);transform:scale(1);transition:opacity .1s linear,-webkit-transform .1s linear;transition:transform .1s linear,opacity .1s linear;transition:transform .1s linear,opacity .1s linear,-webkit-transform .1s linear}.modal-slideLeave-1oSUo{opacity:1;-webkit-transform:translate(0);transform:translate(0)}.modal-slideLeaveActive-313Zm{opacity:.01;-webkit-transform:translateY(2rem) scale(.8);transform:translateY(2rem) scale(.8);transition:opacity .2s linear,-webkit-transform .2s ease-in;transition:transform .2s ease-in,opacity .2s linear;transition:transform .2s ease-in,opacity .2s linear,-webkit-transform .2s ease-in}.spin-content-2Hpan{width:100%;height:inherit}.spin-dyy-3-cwu{position:fixed;z-index:1;top:0;left:0;box-sizing:border-box;width:100%;height:100%;background:hsla(0,0%,88%,.4)}.spin-blur-TOEJc{height:inherit;-webkit-filter:blur(2px) contrast(.8) brightness(.8);filter:blur(2px) contrast(.8) brightness(.8);-webkit-transform:scale(.98);transform:scale(.98)}.spin-laballspin-qTvYF,.spin-laballspin-qTvYF>div{position:absolute;z-index:2;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);box-sizing:border-box}.spin-laballspin-qTvYF{display:block;font-size:0;color:#333}.spin-laballspin-qTvYF.spin-la-dark-2NVKJ{color:#333}.spin-laballspin-qTvYF>div{display:inline-block;float:none;background-color:currentColor;border:0 solid currentColor}.spin-laballspin-qTvYF{width:32px;height:32px}.spin-laballspin-qTvYF>div{position:absolute;top:50%;left:50%;width:8px;height:8px;margin-top:-4px;margin-left:-4px;border-radius:100%;-webkit-animation:spin-ball-spin-2pnBv 1s infinite ease-in-out;animation:spin-ball-spin-2pnBv 1s infinite ease-in-out}.spin-laballspin-qTvYF>div:first-child{top:5%;left:50%;-webkit-animation-delay:-1.125s;animation-delay:-1.125s}.spin-laballspin-qTvYF>div:nth-child(2){top:18.18019485%;left:81.81980515%;-webkit-animation-delay:-1.25s;animation-delay:-1.25s}.spin-laballspin-qTvYF>div:nth-child(3){top:50%;left:95%;-webkit-animation-delay:-1.375s;animation-delay:-1.375s}.spin-laballspin-qTvYF>div:nth-child(4){top:81.81980515%;left:81.81980515%;-webkit-animation-delay:-1.5s;animation-delay:-1.5s}.spin-laballspin-qTvYF>div:nth-child(5){top:95%;left:50%;-webkit-animation-delay:-1.625s;animation-delay:-1.625s}.spin-laballspin-qTvYF>div:nth-child(6){top:81.8198047%;left:18.18019492%;-webkit-animation-delay:-1.75s;animation-delay:-1.75s}.spin-laballspin-qTvYF>div:nth-child(7){top:49.99997508%;left:5.00000512%;-webkit-animation-delay:-1.875s;animation-delay:-1.875s}.spin-laballspin-qTvYF>div:nth-child(8){top:18.17946497%;left:18.18037005%;-webkit-animation-delay:-2s;animation-delay:-2s}.spin-laballspin-qTvYF.spin-la-sm-nSypm{width:16px;height:16px}.spin-laballspin-qTvYF.spin-la-sm-nSypm>div{width:4px;height:4px;margin-top:-2px;margin-left:-2px}.spin-laballspin-qTvYF.spin-la-2x-sqnPZ{width:64px;height:64px}.spin-laballspin-qTvYF.spin-la-2x-sqnPZ>div{width:16px;height:16px;margin-top:-8px;margin-left:-8px}.spin-laballspin-qTvYF.spin-la-3x-zWq0I{width:96px;height:96px}.spin-laballspin-qTvYF.spin-la-3x-zWq0I>div{width:24px;height:24px;margin-top:-12px;margin-left:-12px}@-webkit-keyframes spin-ball-spin-2pnBv{0%,to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}20%{opacity:1}80%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}}@keyframes spin-ball-spin-2pnBv{0%,to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}20%{opacity:1}80%{opacity:0;-webkit-transform:scale(0);transform:scale(0)}}.verify-content-R1VVJ{width:220px;margin:0 auto;padding:20px 0}.verify-content-R1VVJ input{width:100%;height:44px;font-size:16px;font-weight:700;text-align:center;background-color:#eee;box-shadow:inset 2px 2px 0 0 #e5e5e5;border-radius:8px;outline:none}.verify-validbox-3924t{display:table;width:100%;margin:10px auto}.verify-section-1iRfO:first-child{display:table-cell;width:70%;overflow:hidden}.verify-section-1iRfO:first-child input{font-size:16px;border-radius:8px 0 0 8px}.verify-section-1iRfO:nth-child(2){display:table-cell;width:30%;overflow:hidden;vertical-align:top}.verify-section-1iRfO:nth-child(2) span{display:block;width:100%;height:44px;line-height:44px;font-size:14px;color:#fff;text-align:center;vertical-align:middle;border-radius:0 .4em .4em 0;background-color:#108ee9}.verify-section-1iRfO:nth-child(2) .verify-time-3HODU{color:#fff;font-size:14px;background:#ccc;cursor:not-allowed}.verify-btn-4MYg9{display:block;margin:20px auto 0;line-height:2;color:#fff;font-size:20px;font-weight:700;text-align:center;background:#108ee9;border-radius:8px}.verify-tip_show-7qERu{height:18px}.verify-tip_hide-38Oys,.verify-tip_show-7qERu{display:block;color:#710600;font-size:12px;text-align:center;overflow:hidden}.verify-tip_hide-38Oys{height:18px;height:0}.verify-dotting-2sLZ_{display:inline-block;min-width:2px;min-height:2px;box-shadow:2px 0 currentColor,6px 0 currentColor,10px 0 currentColor;-webkit-animation:verify-dot-3ruvS 1.5s infinite step-start both;animation:verify-dot-3ruvS 1.5s infinite step-start both}.verify-dotting-2sLZ_:before{content:"...";content:""}:root .verify-dotting-2sLZ_{margin-right:8px}@-webkit-keyframes verify-dot-3ruvS{25%{box-shadow:none}50%{box-shadow:2px 0 currentColor}75%{box-shadow:2px 0 currentColor,6px 0 currentColor}}@keyframes verify-dot-3ruvS{25%{box-shadow:none}50%{box-shadow:2px 0 currentColor}75%{box-shadow:2px 0 currentColor,6px 0 currentColor}}.verify-enter-Adr5p{display:block;-webkit-transform:translateY(18px);transform:translateY(18px);opacity:.01}.verify-enterActive-LgTlZ{transition:all .15s ease-in}.verify-enterActive-LgTlZ,.verify-leave-ka_0l{display:block;-webkit-transform:translateY(0);transform:translateY(0);opacity:1}.verify-leaveActive-3rYMQ{display:block;-webkit-transform:translateY(-18px);transform:translateY(-18px);opacity:.01;transition:all .15s ease-in}.app-content-2OfhS{box-sizing:border-box;padding:0;line-height:1.5;font-family:Lato,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,PingFang SC,Hiragino Sans GB,Microsoft YaHei,SimSun,sans-serif;font-size:14px;color:#404040}.app-content-2OfhS .app-h2-2Ecu9{margin:1.6em 0 .6em;color:#404040;font-size:18px;font-weight:500}body::-webkit-scrollbar{display:none}code,pre{font-family:Lato,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,PingFang SC,Hiragino Sans GB,Microsoft YaHei,SimSun,sans-serif}.app-head-3-r5d{display:block;width:100%;background:#0e90d2}.app-head-3-r5d h1{display:block;width:960px;box-sizing:border-box;margin:0 auto;color:#fff}.app-hello-2-yTl{box-sizing:border-box;padding-top:50px}.app-hello-2-yTl section{margin-bottom:30px}.app-hello-2-yTl h2{margin:0 0 .6em;color:#404040;font-size:18px;font-weight:500}.app-hello-2-yTl li,.app-hello-2-yTl p{margin-bottom:10px}.app-hello-2-yTl li{display:table;width:100%}.app-hello-2-yTl li span{display:table-cell}.app-hello-2-yTl li span:first-child{width:15px}.app-hello-2-yTl code{padding:2px 4px;color:#c7254e;background-color:#f8f8f8;white-space:nowrap;border-radius:0}.app-hello-2-yTl a{color:#0e90d2;text-decoration:none}.app-hello-2-yTl a:focus,.app-hello-2-yTl a:hover{color:#095f8a}.app-hello-2-yTl .app-git-1CPgW{color:#404040;text-decoration:none;padding:3px 10px 3px 8px;font-size:16px;line-height:22px;border-radius:4px;background-color:#eee;background-image:linear-gradient(180deg,#fcfcfc 0,#eee);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fcfcfc",endColorstr="#eeeeee",GradientType=0);background-repeat:no-repeat;border:1px solid #d5d5d5}.app-hello-2-yTl .app-git-1CPgW:focus,.app-hello-2-yTl .app-git-1CPgW:hover{color:#404040;text-decoration:none;background-color:#ddd;background-image:linear-gradient(180deg,#eee 0,#ddd);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#eeeeee",endColorstr="#dddddd",GradientType=0);border-color:#ccc}.app-hello-2-yTl .app-git-1CPgW svg{width:20px;height:20px;margin-right:5px;fill:#404040;vertical-align:top}.app-hello-2-yTl .app-git-1CPgW svg:focus,.app-hello-2-yTl .app-git-1CPgW svg:hover{color:#095f8a}.app-hello-2-yTl .app-contact-97Y-T{margin-top:200px}.app-hello-2-yTl .app-contact-97Y-T h4{line-height:2.5}.app-hello-2-yTl .app-contact-97Y-T li{margin:10px 0;overflow:hidden;text-align:left}.app-hello-2-yTl .app-contact-97Y-T li div{display:inline-block}.app-hello-2-yTl .app-contact-97Y-T li div:first-child{margin-right:5px}.app-main-3soiG{display:-webkit-box;display:-ms-flexbox;display:flex;width:1000px;box-sizing:border-box;margin:0 auto;padding:20px;background:#fff}.app-left_box-bLhAa{max-width:200px;text-align:left}.app-left_box-bLhAa,.app-right_box-1JgZ2{position:relative;display:block;width:100%;margin:0 auto}.app-right_box-1JgZ2{max-width:640px;box-sizing:border-box;padding-bottom:50px;background:#fff;overflow:hidden}@media screen and (max-width:900px){.app-content-2OfhS .app-head-3-r5d h1{width:100%;padding:0 10px}.app-content-2OfhS .app-main-3soiG{width:100%;padding:10px;display:block;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.app-content-2OfhS .app-left_box-bLhAa{margin:0}.app-content-2OfhS .app-nav-1U4Yi{margin-top:0}.app-content-2OfhS .app-nav-1U4Yi li{padding:0}}.app-nav-1U4Yi{width:100%;margin-top:50px;font-size:14px}.app-nav-1U4Yi li{display:block;box-sizing:border-box;padding-left:20px;line-height:2.5;cursor:pointer}.app-nav-1U4Yi li:hover{background-color:#e7f4fd}.app-nav-1U4Yi li small{font-size:.8em;padding-left:5px}.app-nav-1U4Yi .app-active-2MOLM{color:#dd514c}.app-box-3QqB8{border:1px solid #e9e9e9;border-radius:4px;display:block;position:relative;box-sizing:border-box;margin:0 auto;padding-bottom:10px;transition:all .2s ease}.app-box-3QqB8 .app-git-1CPgW{display:block;text-align:right;box-sizing:border-box;padding-right:10px;color:#0e90d2;fill:#095f8a;text-decoration:underline}.app-box-3QqB8 .app-git-1CPgW:focus,.app-box-3QqB8 .app-git-1CPgW:hover{color:#095f8a;fill:#095f8a}.app-box-3QqB8 .app-git-1CPgW svg{width:20px;height:20px;vertical-align:top;margin-right:5px;fill:inherit}.app-meta-2KGsy{position:relative;border-top:1px solid #e9e9e9;padding:20px 10px 40px;font-size:14px}.app-meta-2KGsy h3{position:absolute;top:-12px;left:10px;width:80px;font-size:14px;text-align:center;background:#fff}.app-meta-2KGsy .app-arrow-2_84v{position:absolute;top:-10px;right:10px;padding:0 5px;background:#fff}.app-meta-2KGsy .app-arrow-2_84v svg{width:22px;height:22px;cursor:pointer;-webkit-transform:rotate(0deg);transform:rotate(0deg);transition:all .5s ease}.app-meta-2KGsy .app-arrow-2_84v svg:hover{fill:#666}.app-meta-2KGsy .app-arrow_up-30ks1{position:absolute;top:-10px;right:10px;padding:0 5px;background:#fff}.app-meta-2KGsy .app-arrow_up-30ks1 svg{width:22px;height:22px;cursor:pointer;-webkit-transform:rotate(0deg);transform:rotate(0deg);transition:all .5s ease}.app-meta-2KGsy .app-arrow_up-30ks1 svg:hover{fill:#666}.app-meta-2KGsy .app-arrow_up-30ks1 svg{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.app-demo-3c3Z0{width:100%;max-width:320px;min-height:100px;box-sizing:border-box;padding:30px 10px 50px}.app-apilist-2Hzwz ul{display:table;width:100%;border-left:1px solid #e9e9e9}.app-apilist-2Hzwz ul:first-child{border-top:1px solid #e9e9e9}.app-apilist-2Hzwz ul li{display:table-cell;width:25%;padding:10px;border:1px solid #e9e9e9;border-top:none;border-left:none;word-wrap:break-word;word-break:break-all} --------------------------------------------------------------------------------