Commit ef96cbf7 by icarus

feat: add a new project

parent 18a4dc78
Hello Hackthon! # Rate
\ No newline at end of file ---
React | ES6 | webpack | ESlint | HMR
## Desc
* 评分插件
* 支持总分设置
* 支持默认值设置
* 支持onChange事件
* 支持不可变更性
## Usage
```js
<Rate
total={10}
disabled={false}
value={score}
onChange={this.onChange}
/>
```
## Examples
Look the directory `/examples`
## API
### Props
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 100px;">name</th>
<th style="width: 50px;">type</th>
<th style="width: 50px;">default</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>value</td>
<td>number.isRequired</td>
<td>0</td>
<td>当前值</td>
</tr>
<tr>
<td>onChange</td>
<td>func.isRequired</td>
<td></td>
<td>change事件</td>
</tr>
<tr>
<td>disabled</td>
<td>bool</td>
<td>false</td>
<td>是否禁用</td>
</tr>
<tr>
<td>total</td>
<td>number</td>
<td>5</td>
<td>总数</td>
</tr>
<tr>
<td>defaultValue</td>
<td>number</td>
<td>0</td>
<td>默认值</td>
</tr>
</tbody>
</table>
## Note
Thank you to give me many importance suggestions!
## Development
```bash
npm install
npm start
```
[node_modules](https://pan.baidu.com/s/1slEzpAt)最新下载地址(https://pan.baidu.com/s/1slEzpAt)
@font-face {
font-family: 'icon-blog';
src: url('fonts/icon-blog.eot') format('embedded-opentype'),
url('fonts/icon-blog.ttf') format('truetype'),
url('fonts/icon-blog.woff') format('woff'),
url('fonts/icon-blog.svg') format('svg');
font-weight: normal;
font-style: normal;
}
[class^="icon-blog"], [class*=" icon-blog"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icon-blog' !important;
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-blog-down:before {
content: "\e913";
}
.icon-blog-up:before {
content: "\e900";
}
.icon-blog-edit:before {
content: "\e95c";
}
.icon-blog-AddTo:before {
content: "\e93b";
}
.icon-blog-blank:before {
content: "\e93a";
}
.icon-blog-follow:before {
content: "\e941";
}
.icon-blog-ArrowheadDown:before {
content: "\e901";
}
.icon-blog-ArrowheadUp:before {
content: "\e939";
}
.icon-blog-AlreadyConcern:before {
content: "\e906";
}
.icon-blog-drop-down:before {
content: "\e937";
}
.icon-blog-NewMessage:before {
content: "\e938";
}
.icon-blog-delete:before {
content: "\e936";
}
.icon-blog-Explain:before {
content: "\e935";
}
.icon-blog-delay:before {
content: "\e931";
}
.icon-blog-o:before {
content: "\e932";
}
.icon-blog-solid:before {
content: "\e933";
}
.icon-blog-Submit:before {
content: "\e934";
}
.icon-blog-Pay:before {
content: "\e922";
}
.icon-blog:before {
content: "\e923";
}
.icon-blog-down2:before {
content: "\e919";
}
.icon-blog-up2:before {
content: "\e920";
}
.icon-blog-Absenteeism:before {
content: "\e924";
}
.icon-blog-checkbox:before {
content: "\e925";
}
.icon-blog-Explain-o:before {
content: "\e926";
}
.icon-blog-index:before {
content: "\e927";
}
.icon-blog-Late:before {
content: "\e928";
}
.icon-blog-left:before {
content: "\e929";
}
.icon-blog-normal:before {
content: "\e92a";
}
.icon-blog-remind:before {
content: "\e92b";
}
.icon-blog-ReportForm:before {
content: "\e92c";
}
.icon-blog-right:before {
content: "\e92d";
}
.icon-blog-Uncommitted-o:before {
content: "\e92e";
}
.icon-blog-Uncommitted:before {
content: "\e92f";
}
.icon-blog-Unhappy:before {
content: "\e930";
}
.icon-blog-at:before {
content: "\e902";
}
.icon-blog-branch:before {
content: "\e903";
}
.icon-blog-CancelConcern:before {
content: "\e904";
}
.icon-blog-Comment:before {
content: "\e905";
}
.icon-blog-Customer:before {
content: "\e93c";
}
.icon-blog-Document:before {
content: "\e907";
}
.icon-blog-Emoji:before {
content: "\e908";
}
.icon-blog-Enclosure:before {
content: "\e909";
}
.icon-blog-Good:before {
content: "\e90a";
}
.icon-blog-Lock:before {
content: "\e90b";
}
.icon-blog-MessageReminder:before {
content: "\e90c";
}
.icon-blog-Modular:before {
content: "\e90d";
}
.icon-blog-Mood:before {
content: "\e90e";
}
.icon-blog-MutualConcern:before {
content: "\e90f";
}
.icon-blog-NewPacket:before {
content: "\e910";
}
.icon-blog-NextPage:before {
content: "\e911";
}
.icon-blog-NoData:before {
content: "\e912";
}
.icon-blog-Note:before {
content: "\e93d";
}
.icon-blog-Personnel:before {
content: "\e914";
}
.icon-blog-Previous_page:before {
content: "\e915";
}
.icon-blog-Process:before {
content: "\e916";
}
.icon-blog-Project:before {
content: "\e917";
}
.icon-blog-region:before {
content: "\e918";
}
.icon-blog-Schedule:before {
content: "\e91a";
}
.icon-blog-Score-o:before {
content: "\e91b";
}
.icon-blog-Score:before {
content: "\e91c";
}
.icon-blog-Task:before {
content: "\e91d";
}
.icon-blog-VisiblePart:before {
content: "\e91e";
}
.icon-blog-next-month:before {
content: "\e91f";
}
.icon-blog-last-month:before {
content: "\e921";
}
@import "icon.css";
.wea-rate {
padding: 0;
margin: 0;
.wea-r-item {
display: inline-block;
vertical-align: middle;
cursor: default;
transition: all 0.25s ease 0s;
}
.wea-r-text {
font-size: 12px;
margin-right: 12px;
color: #eaeaea;
}
.wea-r-text-hover {
font-size: 12px;
margin-right: 12px;
color: #ff7777;
}
.wea-r-score {
padding: 4px 2px;
font-size: 16px;
color: #eaeaea;
}
.wea-r-score-hover{
padding: 4px 2px;
font-size: 16px;
color: #eaeaea;
cursor: pointer;
&:hover {
transform: scale(1.2, 1.2)
}
}
.wea-r-score-selected {
color: #ff7777;
}
}
.app {
text-size-adjust: none;
font-family: helvetica, arial, sans-serif;
line-height: 200%;
padding: 6px 20px 30px;
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example Index</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
import React from "react";
import ReactDOM from "react-dom";
import { AppContainer } from "react-hot-loader";
// AppContainer 是一个 HMR 必须的包裹(wrapper)组件
import App from "./views/App";
const render = (Component) => {
ReactDOM.render(
<AppContainer>
<Component/>
</AppContainer>,
document.getElementById("root")
);
};
render(App);
// 模块热替换的 API
if (module.hot) {
module.hot.accept("./views/App", () => {
render(App)
});
}
// npm install --save-dev webpack webpack-dev-server
// npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
// npm install --save-dev style-loader css-loader
// npm install --save react react-dom react-hot-loader@next
import React, {Component} from 'react';
import '../assets/App.css';
import Rate from "../../index"
class App extends Component {
constructor() {
super()
this.state = {
score: 5
}
}
render() {
const {score} = this.state
return (
<div className="app">
<h2>Hello,</h2>
<Rate
total={10}
disabled={false}
value={score}
onChange={this.onChange}
/>
</div>
)
}
onChange = (score) => {
this.setState({score: score})
}
}
export default App;
export default from "./src/index"
{
"name": "webpack_HMR",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server"
},
"author": "icarus",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.24.1",
"babel-eslint": "^6.1.2",
"babel-loader": "^7.0.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-export-extensions": "^6.22.0",
"babel-plugin-transform-function-bind": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.1",
"eslint": "^3.19.0",
"eslint-config-airbnb": "^15.1.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-react": "^7.2.0",
"file-loader": "^0.11.2",
"less": "^2.7.2",
"less-loader": "^4.0.5",
"prop-types": "^15.5.10",
"style-loader": "^0.17.0",
"url-loader": "^0.5.9",
"webpack": "^2.4.1",
"webpack-dev-server": "^2.4.5"
},
"dependencies": {
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-hot-loader": "^3.0.0-beta.6"
}
}
import React, {Component} from 'react'
import T from 'prop-types'
import '../assets/index.less'
class Rate extends Component {
constructor(props) {
super(props)
const {defaultValue = 0, value = 0, total = 5, disabled = false} = props
this.state = {
value: value || defaultValue,
currentValue: value || defaultValue,
total: total,
disabled: disabled
}
}
componentWillReceiveProps(props) {
const {value} = props
this.setState({value: value})
}
render() {
const {className = ""} = this.props,
{value, currentValue, total, disabled} = this.state,
rates = []
rates.push(<li key="text" className={"wea-r-item " + (currentValue ? "wea-r-text-hover" : "wea-r-text")}>{currentValue}</li>)
if (disabled) {
for (let i = 0; i < total; i++) {
if (i < currentValue) {
rates.push(
<li key={i} className="wea-r-item wea-r-score wea-r-score-selected icon-blog-Score"/>
)
} else {
rates.push(
<li key={i} className="wea-r-item wea-r-score icon-blog-Score-o"/>
)
}
}
return <ul className={"wea-rate " + className} >{rates}</ul>
} else {
for (let i = 0; i < total; i++) {
if (i < currentValue) {
rates.push(
<li
key={i}
value={i + 1}
className="wea-r-item wea-r-score-hover wea-r-score-selected icon-blog-Score"
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
/>
)
} else {
rates.push(
<li
key={i}
value={i + 1}
className="wea-r-item wea-r-score-hover icon-blog-Score-o"
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
/>
)
}
}
return (
<ul className={"wea-rate " + className} onClick={this.onClick}>
{rates}
</ul>
)
}
}
onClick = (e) => {
const {onChange} = this.props
if (onChange) onChange(e.target.value)
}
onMouseEnter = (e) => {
this.setState({currentValue: e.target.value})
}
onMouseLeave = (e) => {
this.setState({currentValue: this.state.value})
}
}
Rate.propTypes = {
value: T.number.isRequired,
onChange: T.func.isRequired,
disabled: T.bool,
total: T.number,
defaultValue: T.number
}
Rate.defaultProps = {
value: 0,
disabled: false,
total: 5,
defaultValue: 0
}
export default Rate
const {resolve} = require('path');
const webpack = require('webpack');
require("babel-polyfill");
module.exports = {
context: resolve(__dirname, 'examples'),
entry: [
'babel-polyfill',
'react-hot-loader/patch',
// 开启 React 代码的模块热替换(HMR)
'webpack-dev-server/client?http://localhost:8888',
// 为 webpack-dev-server 的环境打包代码
// 然后连接到指定服务器域名与端口
'webpack/hot/only-dev-server',
// 为热替换(HMR)打包好代码
// only- 意味着只有成功更新运行代码才会执行热替换(HMR)
'./index.js'
// 我们 app 的入口文件
],
output: {
filename: 'bundle.js',
// 输出的打包文件
path: resolve(__dirname, 'examples/dist'),
publicPath: '/'
// 对于热替换(HMR)是必须的,让 webpack 知道在哪里载入热更新的模块(chunk)
},
devtool: 'inline-source-map',
devServer: {
hot: true,
// 开启服务器的模块热替换(HMR)
contentBase: resolve(__dirname, 'examples/dist'),
// 输出文件的路径
publicPath: '/',
// 和上文 output 的“publicPath”值保持一致
port: 8888
},
module: {
rules: [
{
enforce: "pre",
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
},
{
test: /\.css|\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'],
},
{
test : /\.woff/,
loader : 'url-loader?prefix=font/&limit=10000&mimetype=application/font-woff'
}, {
test : /\.ttf/,
loader : 'file-loader?prefix=font/'
}, {
test : /\.eot/,
loader : 'file-loader?prefix=font/'
}, {
test : /\.svg/,
loader : 'file-loader?prefix=font/'
}
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// 开启全局的模块热替换(HMR)
new webpack.NamedModulesPlugin(),
// 当模块热替换(HMR)时在浏览器控制台输出对用户更友好的模块名字信息
],
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment