Skip to content

Commit

Permalink
✨ [feature] finish Select component.
Browse files Browse the repository at this point in the history
  • Loading branch information
lanjingling0510 committed Mar 13, 2017
1 parent cc24747 commit 8b48cb9
Show file tree
Hide file tree
Showing 16 changed files with 343 additions and 61 deletions.
Empty file removed components/dropdown/Dropdown.js
Empty file.
Empty file removed components/dropdown/index.js
Empty file.
2 changes: 2 additions & 0 deletions components/identifiers.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export const BUTTON = 'RTButton';
export const RIPPLE = 'RTRIPPLE';
export const ICON = 'RTICON';
export const SELECT = 'SELECT';
export const SELECT_INPUT = 'RTSELECTINPUT';
export const MENU = 'RTMENU';
export const POPUP = 'POPUP';
2 changes: 1 addition & 1 deletion components/menu/config.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
--menu-item-icon-size: calc(1.6 * var(--menu-item-icon-font-size));
--menu-item-height: calc(4.2 * var(--unit));
--menu-item-padding: calc(1.6 * var(--unit));
--menu-item-font-size: calc(1.6 * var(--unit));
--menu-item-font-size: calc(1.4 * var(--unit));
--menu-divider-height: calc((4.8 / 4) * var(--unit));
--menu-icon-size: calc(2.3 * var(--unit));
--menu-icon-ripple-duration: 650ms;
Expand Down
2 changes: 1 addition & 1 deletion components/modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Modal extends Component {
}

updateAppendElements() {
render(<span>{getAppendedElements()}</span>, appendElementContainer);
render(<span data-react-toolbox="Modal">{getAppendedElements()}</span>, appendElementContainer);
}

removeAppendElement() {
Expand Down
9 changes: 9 additions & 0 deletions components/popup/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Popup from './Popup';
import theme from './theme.css';
import { themr } from 'react-css-themr';
import { POPUP } from '../identifiers';

const ThemedPopup = themr(POPUP, theme)(Popup);

export default ThemedPopup;
export {ThemedPopup};
70 changes: 69 additions & 1 deletion components/popup/popup.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,81 @@
import React, { PropTypes } from 'react';
import { findDOMNode } from 'react-dom';
import domAlign from 'dom-align';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';

class Popup extends React.Component {

static propTypes = {
align: PropTypes.object,
mask: PropTypes.bool,
theme: PropTypes.object,
getRootDomNode: PropTypes.func,
}

componentDidMount() {
const source = this.getPopupDomNode();
const target = this.props.getRootDomNode();
const align = this.props.align;
this.setPopupAlign(source, target, align);
}

setPopupAlign = (sourceNode, targetNode, popupAlign) => {
domAlign(sourceNode, targetNode, popupAlign);
}

getMaskElement = () => {
const {theme, mask} = this.props;

const maskTheme = {
appear: theme['mask-appear'],
appearActive: theme['mask-appear-active'],
};

return mask ?
<ReactCSSTransitionGroup
transitionName={maskTheme}
transitionAppear={true}
transitionAppearTimeout={500}
transitionEnter={false}
transitionLeave={false}>
<div className={theme.mask}></div>
</ReactCSSTransitionGroup> : null;
}

getPopupElement = () => {
const {children, theme} = this.props;
const newProps = {
...children.props,
key: 'popup',
ref: 'popup',
};

const popupTheme = {
appear: theme['popup-appear'],
appearActive: theme['popup-appear-active'],
};

return (
<ReactCSSTransitionGroup
transitionName={popupTheme}
transitionAppear={true}
transitionAppearTimeout={500}
transitionEnter={false}
transitionLeave={false}>
{React.cloneElement(children, newProps)}
</ReactCSSTransitionGroup>
);
}

getPopupDomNode = () => {
return findDOMNode(this.refs.popup);
}

render () {
return (
<div>

{this.getMaskElement()}
{this.getPopupElement()}
</div>
)
}
Expand Down
33 changes: 33 additions & 0 deletions components/popup/theme.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.mask {
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
background-color: #373737;
background-color: rgba(55,55,55,.6);
height: 100%;
z-index: 1000;
}

.popup-appear {
opacity: 0.01;
transform: translate(0, 10px);
}

.popup-appear-active {
opacity: 1;
transform: translate(0, 0);
transition: opacity .2s ease-in, transform .2s ease-in;
}

.mask-appear {
opacity: 0.01;
transform: translate(0, 10px);
}

.mask-appear-active {
opacity: 1;
transform: translate(0, 0);
transition: opacity .2s ease-in, transform .2s ease-in;
}
104 changes: 104 additions & 0 deletions components/select/Select.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React, { Component, PropTypes } from 'react';

const popupAlign = {
points: ['tl', 'bl'],
offset: [0, 10],
};

const factory = (Trigger, SelectInput, Menu, MenuItem) => {
class Select extends Component {

static propTypes = {
value: PropTypes.any,
data: PropTypes.array,
onChange: PropTypes.func,
}

static defaultProps = {
onChange: () => void 0,
}

constructor(props) {
super(props);

let value;
if ('value' in props) {
value = props.value;
} else {
value = props.data[0].value;
}

this.state = {
value,
open: false,
}
}

state = {
open: false,
value: this.props.data,
}

componentWillReceiveProps(nextProps) {
if ('value' in nextProps) {
this.setState({ value: nextProps.value });
}
}

getMenus = (list) => {
return (
<Menu>
{list.map(this.getMenu)}
</Menu>
);
}

getMenu = (item) => {
const theme = this.props.theme;
return (
<MenuItem
theme={theme}
key={item.label}
onClick={this.handleMenuItemClick(item)}>
{item.label}
</MenuItem>
);
}

handleMenuItemClick = item => () => {
this.handleSelectToggle();
this.setState({ value: item.value });
this.props.onChange(item);
}

handleSelectToggle = () => {
this.setState({ open: !this.state.open });
}

render() {
const props = this.props;
const state = this.state;
const menu = this.getMenus(props.data);
const selectedItem =
props.data.find(item => item.value === state.value) ||
props.data[0];

return (
<Trigger
popupAlign={popupAlign}
popupVisible={state.open}
onPopupVisibleChange={this.handleSelectToggle}
popup={menu}>
<SelectInput
selectedItem={selectedItem}
isActive={state.open}
onClick={this.handleSelectToggle} />
</Trigger>
);
}
}

return Select;
};

export {factory as selectFactory};
18 changes: 18 additions & 0 deletions components/select/config.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
:root {
--menu-expand-duration: 0.3s;
--menu-fade-duration: 0.2s;
--menu-ripple-delay: 0.3s;
--menu-background-color: var(--color-white);
--menu-padding: calc(0.8 * var(--unit)) 0;
--menu-outline-border-radius: calc(0.2 * var(--unit));
--menu-item-hover-background: var(--palette-grey-200);
--menu-item-selected-background: color(var(--color-primary) a(10%));
--menu-item-icon-font-size: calc(2.4 * var(--unit));
--menu-item-icon-size: calc(1.6 * var(--menu-item-icon-font-size));
--menu-item-height: calc(3.2 * var(--unit));
--menu-item-padding: calc(1.6 * var(--unit));
--menu-item-font-size: calc(1.4 * var(--unit));
--menu-divider-height: calc((4.8 / 4) * var(--unit));
--menu-icon-size: calc(2.3 * var(--unit));
--menu-icon-ripple-duration: 650ms;
}
18 changes: 18 additions & 0 deletions components/select/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {selectFactory} from './Select';
import theme from './theme.css';
import { themr } from 'react-css-themr';
import { SELECT, MENU } from '../identifiers';
import Trigger from '../trigger';
import Menu from '../menu/Menu';
import {menuItemFactory} from '../menu/MenuItem';
import themedRippleFactory from '../ripple';

import SelectInput from '../select_input';
const ThemedMenuItem= themr(MENU, theme)(menuItemFactory(themedRippleFactory({})));
const ThemedMenu= themr(MENU, theme)(Menu);

const Select = selectFactory(Trigger, SelectInput, ThemedMenu, ThemedMenuItem);
const ThemedSelect = themr(SELECT, theme)(Select);

export default ThemedSelect;
export {ThemedSelect as Select};
36 changes: 36 additions & 0 deletions components/select/theme.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@import '../colors.css';
@import '../variables.css';
@import './config.css';

.menu {
box-shadow: 0 1px 6px rgba(0,0,0,.2);
border-radius: 4px;
z-index: 1050;
float: left;
white-space: nowrap;
outline: none;
margin: 0;
padding: 0;
list-style: none;
color: rgba(0,0,0,.65);
background: #fff;
overflow: hidden;
min-width: 120px;
}

.menuItem {
color: var(--color-text);
font-size: var(--menu-item-font-size);
height: var(--menu-item-height);
line-height: var(--menu-item-height);
overflow: hidden;
padding: 0 var(--menu-item-padding);
position: relative;
user-select: none;
text-align: center;

&:not(.disabled):hover {
background-color: var(--menu-item-hover-background);
cursor: pointer;
}
}
Loading

0 comments on commit 8b48cb9

Please sign in to comment.