mirror of
https://github.com/wassname/talk.git
synced 2026-09-12 13:01:11 +08:00
Adding Dropdown and Option Compoennt
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
.dropdown {
|
||||
position: relative;
|
||||
width: 150px;
|
||||
height: 36px;
|
||||
background: #2c2c2c;
|
||||
padding: 10px 15px;
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.label {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.list {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 10px;
|
||||
color: #2c2c2c;
|
||||
border-radius: 2px;
|
||||
background: white;
|
||||
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||
width: 100%;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
transform: scale(0);
|
||||
transition: transform .3s cubic-bezier(.4,0,.2,1),opacity .2s cubic-bezier(.4,0,.2,1),-webkit-transform .3s cubic-bezier(.4,0,.2,1);
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
.listActive {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
font-size: 1.2rem;
|
||||
vertical-align: middle;
|
||||
top: 13px;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Dropdown.css';
|
||||
import Icon from './Icon';
|
||||
import cn from 'classnames';
|
||||
import ClickOutside from 'coral-framework/components/ClickOutside';
|
||||
|
||||
class Dropdown extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
selected: {
|
||||
label: props.label || '',
|
||||
value: props.value || ''
|
||||
},
|
||||
isOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
if (newProps.value && newProps.value !== this.state.selected.value) {
|
||||
this.setState({
|
||||
selected: {
|
||||
label: newProps.label,
|
||||
value: newProps.value
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
compoentDidMount() {
|
||||
document.addEventListener('click', this.handleClick, false);
|
||||
document.addEventListener('touchend', this.handleClick, false);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('click', this.handleClick, false);
|
||||
document.removeEventListener('touchend', this.handleClick, false);
|
||||
}
|
||||
|
||||
fireChange = (newState) => {
|
||||
if (newState.selected !== this.state.selected && this.props.onChange) {
|
||||
this.props.onChange(newState.selected.value);
|
||||
}
|
||||
}
|
||||
|
||||
setValue = (value, label) => {
|
||||
const newState = {
|
||||
selected: {
|
||||
label: label,
|
||||
value: value
|
||||
},
|
||||
isOpen: false
|
||||
};
|
||||
this.fireChange(newState);
|
||||
this.setState(newState);
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
this.setState({
|
||||
isOpen: !this.state.isOpen
|
||||
});
|
||||
}
|
||||
|
||||
hideMenu = () => {
|
||||
this.setState({
|
||||
isOpen: false
|
||||
});
|
||||
}
|
||||
|
||||
renderLabel() {
|
||||
if (this.props.label) {
|
||||
return this.props.label;
|
||||
} else if (this.props.value) {
|
||||
return this.props.value;
|
||||
} else {
|
||||
return this.props.placeholder;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ClickOutside onClickOutside={this.hideMenu}>
|
||||
<div className={styles.dropdown} onClick={this.handleClick}>
|
||||
{this.props.icon && <Icon name={this.props.icon} className={styles.icon} />}
|
||||
<span className={styles.label}>{this.renderLabel()}</span>
|
||||
{this.state.isOpen ? <Icon name="keyboard_arrow_up" className={styles.arrow} /> : <Icon name="keyboard_arrow_down" className={styles.arrow} />}
|
||||
<ul className={cn(styles.list, {[styles.listActive] : this.state.isOpen})}>
|
||||
{React.Children.toArray(this.props.children)
|
||||
.map((child) =>
|
||||
React.cloneElement(child, {
|
||||
key: child.props.value,
|
||||
onClick: () => this.setValue(child.props.value, child.props.children)
|
||||
}))}
|
||||
</ul>
|
||||
</div>
|
||||
</ClickOutside>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Dropdown.propTypes = {
|
||||
placeholder: PropTypes.string,
|
||||
icon: PropTypes.string,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
label: PropTypes.string,
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.number,
|
||||
PropTypes.string
|
||||
]),
|
||||
};
|
||||
|
||||
export default Dropdown;
|
||||
@@ -1,3 +1,9 @@
|
||||
.Option {
|
||||
|
||||
.option {
|
||||
padding: 10px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
background-color: #eee;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -1,14 +1,18 @@
|
||||
import React from 'react';
|
||||
import {Option as OptionMDL} from 'react-mdl-selectfield';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Option.css';
|
||||
import cn from 'classnames';
|
||||
|
||||
const Option = (props) => {
|
||||
const {children, ...attrs} = props;
|
||||
return (
|
||||
<OptionMDL className={styles.Option} {...attrs}>
|
||||
{children}
|
||||
</OptionMDL>
|
||||
);
|
||||
const Option = ({className, children, onClick}) => (
|
||||
<li className={cn(styles.option, className)} onClick={onClick}>
|
||||
{children || ''}
|
||||
</li>
|
||||
);
|
||||
|
||||
Option.propTypes = {
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.string,
|
||||
onClick: PropTypes.func
|
||||
};
|
||||
|
||||
export default Option;
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
.Select {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
background: #2c2c2c;
|
||||
padding: 10px 15px;
|
||||
box-sizing: border-box;
|
||||
color: white;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
|
||||
|
||||
> div {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 7px;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 0;
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.7px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import React from 'react';
|
||||
import {SelectField} from 'react-mdl-selectfield';
|
||||
import styles from './Select.css';
|
||||
|
||||
const Select = (props) => {
|
||||
const {children, ...attrs} = props;
|
||||
return (
|
||||
<SelectField className={styles.Select} {...attrs}>
|
||||
{children}
|
||||
</SelectField>
|
||||
);
|
||||
};
|
||||
|
||||
export default Select;
|
||||
@@ -21,10 +21,10 @@ export {default as Success} from './components/Success';
|
||||
export {default as Pager} from './components/Pager';
|
||||
export {default as Wizard} from './components/Wizard';
|
||||
export {default as WizardNav} from './components/WizardNav';
|
||||
export {default as Select} from './components/Select';
|
||||
export {default as Option} from './components/Option';
|
||||
export {default as SnackBar} from './components/SnackBar';
|
||||
export {default as TextArea} from './components/TextArea';
|
||||
export {default as Drawer} from './components/Drawer';
|
||||
export {default as Label} from './components/Label';
|
||||
export {default as FlagLabel} from './components/FlagLabel';
|
||||
export {default as Dropdown} from './components/Dropdown';
|
||||
export {default as Option} from './components/Option';
|
||||
|
||||
Reference in New Issue
Block a user