Skip to content

Instantly share code, notes, and snippets.

@YanceyOfficial
Last active January 28, 2019 09:31
Show Gist options
  • Save YanceyOfficial/8ea13faf6697e7a4bee1d206acb756f2 to your computer and use it in GitHub Desktop.
Save YanceyOfficial/8ea13faf6697e7a4bee1d206acb756f2 to your computer and use it in GitHub Desktop.
[源码] 尝试创建一个React通用UI组件
import React, { Component } from 'react';
import Button from './components/Button/Button';
import { useState } from 'react';
import { library } from '@fortawesome/fontawesome-svg-core';
import {
faSpinner,
faTrashAlt,
faSave,
} from '@fortawesome/free-solid-svg-icons';
library.add(faSpinner, faTrashAlt, faSave);
class App extends Component {
render() {
return (
<div className='App'>
<Button type='default'>default</Button>
<Button type='primary'>primary</Button>
<Button type='danger'>danger</Button>
<Button type='default'>default</Button>
<Button type='primary' icon='save'>
save
</Button>
<Button type='danger' icon='trash-alt'>
delete
</Button>
<Button disabled>disabled</Button>
<Button>no any props</Button>
<Button icon='save' loading>
loading
</Button>
<Example />
</div>
);
}
}
export default App;
button {
font-family: 'Roboto', "Helvetica", "Arial", sans-serif;
color: #fff;
box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 3px 1px -2px rgba(0, 0, 0, 0.12);
padding: 6px 16px;
margin: 8px;
font-size: 14px;
font-weight: 500;
line-height: 1.75;
letter-spacing: .4px;
border: none;
border-radius: 4px;
outline: none;
cursor: pointer;
text-transform: uppercase;
user-select: none;
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}
button:hover {
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}
.default {
color: rgba(0, 0, 0, 0.87);
background-color: #e0e0e0;
}
.default:hover {
background: #d5d5d5;
}
.primary {
color: #fff;
background-color: #2196f3;
}
.primary:hover {
background: #1976d2;
}
.danger {
color: #fff;
background-color: rgb(225, 0, 80);
}
.danger:hover {
background: rgb(157, 0, 56);
}
.disabled {
color: rgba(0, 0, 0, 0.26);
box-shadow: none;
background-color: rgba(0, 0, 0, 0.12);
}
.disabled:hover {
background: rgba(0, 0, 0, 0.12);
cursor: not-allowed;
}
svg {
margin-left: 8px;
}
.fa-spinner {
animation: circle infinite linear 1000ms;
}
@keyframes circle {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
import React, { Component } from 'react';
import './Button.css';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const needSpace = child =>
/^[\u4E00-\u9FA5\uF900-\uFA2D]+$/.test(child) && child.length === 2
? child.split('').join(' ')
: child;
class Button extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
// todo
}
handleClick = e => {
const { loading, disabled } = this.state;
const { onClick } = this.props;
if (loading || disabled) {
return false;
} else {
if (onClick) {
onClick(e);
}
}
};
render() {
const loading = this.props.loading;
const icon = loading ? 'spinner' : this.props.icon;
const iconNode = icon ? <FontAwesomeIcon icon={icon} /> : null;
const children = this.props.children;
const type = this.props.type;
const disabled = this.props.disabled;
const kids = React.Children.map(children, child => needSpace(child));
return (
<button
className={loading || disabled ? 'disabled' : type}
disabled={loading || disabled}
icon={icon}
onClick={this.handleClick}
>
{kids}
{iconNode}
</button>
);
}
}
Button.defaultProps = {
type: 'default',
disabled: false,
loading: false,
icon: null,
};
export default Button;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment