Skip to content

Commit

Permalink
SelectField + TextField refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismcv committed Mar 7, 2016
1 parent 133f660 commit f0b7887
Show file tree
Hide file tree
Showing 10 changed files with 766 additions and 192 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import SelectField from 'material-ui/lib/select-field';
import MenuItem from 'material-ui/lib/menus/menu-item';

export default class SelectFieldExampleSimple extends React.Component {

constructor(props) {
super(props);
this.state = {
open: true,
value: 2,
};
}

handleChange = (event, index, value) => this.setState({value});

render() {
const {open} = this.state;
return (
<div>
<SelectField
open={open}
onRequestClose={() => this.setState({open: false})}
value={this.state.value}
onChange={this.handleChange}
>
<MenuItem value={1} primaryText="Never" />
<MenuItem value={2} primaryText="Every Night" />
<MenuItem value={3} primaryText="Weeknights" />
<MenuItem value={4} primaryText="Weekends" />
<MenuItem value={5} primaryText="Weekly" />
</SelectField>
<br />
<SelectField value={1} disabled={true}>
<MenuItem value={1} primaryText="Never" />
<MenuItem value={2} primaryText="Every Night" />
</SelectField>
</div>
);
}
}
10 changes: 10 additions & 0 deletions docs/src/app/components/pages/components/SelectField/Page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import SelectFieldExampleCustomLabel from './ExampleCustomLabel';
import selectFieldExampleCustomLabelCode from '!raw!./ExampleCustomLabel';
import SelectFieldExampleFloatingLabel from './ExampleFloatingLabel';
import selectFieldExampleFloatingLabelCode from '!raw!./ExampleFloatingLabel';
import SelectFieldExampleOpenOnMount from './ExampleOpenOnMount';
import selectFieldExampleOpenOnMountCode from '!raw!./ExampleOpenOnMount';
import SelectFieldExampleError from './ExampleError';
import selectFieldExampleErrorCode from '!raw!./ExampleError';
import selectFieldCode from '!raw!material-ui/lib/SelectField/SelectField';
Expand Down Expand Up @@ -70,6 +72,14 @@ const SelectFieldPage = () => (
>
<SelectFieldExampleError />
</CodeExample>

<CodeExample
title="Open on mount"
description={descriptions.errorText}
code={selectFieldExampleOpenOnMountCode}
>
<SelectFieldExampleOpenOnMount />
</CodeExample>
<PropTypeDescription code={selectFieldCode} />
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"homepage": "http://material-ui.com/",
"dependencies": {
"inline-style-prefixer": "^1.0.1",
"keycode": "^2.1.0",
"keycode": "^2.1.1",
"lodash.flowright": "^3.2.1",
"lodash.merge": "^4.1.0",
"lodash.throttle": "^4.0.0",
Expand Down
217 changes: 163 additions & 54 deletions src/SelectField/SelectField.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
import React from 'react';
import TextField from '../text-field';
import DropDownMenu from '../DropDownMenu';
import ReactDom from 'react-dom';
import TextFieldDecorator from '../TextField/TextFieldDecorator';
import SelectFieldMenu from './SelectFieldMenu';
import SelectFieldLabel from './SelectFieldLabel';
import getMuiTheme from '../styles/getMuiTheme';

function getStyles(props) {
return {
label: {
paddingLeft: 0,
top: props.floatingLabelText ? 6 : -4,
},
icon: {
right: 0,
top: props.floatingLabelText ? 22 : 14,
},
hideDropDownUnderline: {
borderTop: 'none',
},
};
}
import keycode from 'keycode';

const SelectField = React.createClass({

Expand Down Expand Up @@ -82,6 +69,11 @@ const SelectField = React.createClass({
*/
iconStyle: React.PropTypes.object,

/**
* The id prop for the text field.
*/
id: React.PropTypes.string,

/**
* Overrides the styles of label when the `SelectField` is inactive.
*/
Expand All @@ -102,6 +94,15 @@ const SelectField = React.createClass({
*/
onFocus: React.PropTypes.func,

/**
* Callback function that is fired when the `SelectField` is closed.
*/
onRequestClose: React.PropTypes.func,

/**
* Property controlling whether the `SelectField` is open. Use to open `DropDown` on mount.
*/
open: React.PropTypes.bool,
/**
* The style object to use to override the `DropDownMenu`.
*/
Expand All @@ -112,6 +113,8 @@ const SelectField = React.createClass({
*/
style: React.PropTypes.object,

tabIndex: React.PropTypes.number,

/**
* Override the inline-styles of the underline element when disabled.
*/
Expand Down Expand Up @@ -146,12 +149,16 @@ const SelectField = React.createClass({
autoWidth: false,
disabled: false,
fullWidth: false,
id: 'select',
open: false,
tabIndex: 0,
};
},

getInitialState() {
return {
muiTheme: this.context.muiTheme || getMuiTheme(),
open: false,
};
},

Expand All @@ -161,70 +168,172 @@ const SelectField = React.createClass({
};
},

componentDidMount() {
if (this.props.open) {
/* eslint-disable */
/* because we're using ref for popover anchorEl */
this.setState({open: true});
}
},

componentWillReceiveProps(nextProps, nextContext) {
this.setState({
muiTheme: nextContext.muiTheme || this.state.muiTheme,
open: nextProps.open,
});
},

componentWillUnmount() {
this.label = null;
},

handleMenuRequestClose() {
this.setState({
open: false,
isFocused: true,
}, () => this.label.focus());
const {onRequestClose} = this.props;
return onRequestClose ? onRequestClose() : null;
},

handleTouchTap() {
if (this.props.disabled)
return;

this.setState({
open: true,
isFocused: false,
});
},

onFocus() {
if (this.props.disabled)
return;
this.setState({isFocused: true});
const {onFocus} = this.props;
return onFocus ? onFocus() : null;
},

onBlur() {
const {onBlur} = this.props;
this.setState({isFocused: false});
return onBlur ? onBlur() : null;
},

handleKeyDown(event) {
switch (keycode(event)) {
case 'enter':
case 'space':
case 'down':
event.preventDefault();
if (!this.props.disabled) {
this.setState({
open: !this.state.open,
anchorEl: this.refs.root,
});
}
}
},

render() {
const {
autoWidth,
children,
style,
labelStyle,
iconStyle,
underlineDisabledStyle,
underlineFocusStyle,
underlineStyle,
errorStyle,
selectFieldRoot,
disabled,
floatingLabelText,
errorStyle,
errorText,
floatingLabelStyle,
floatingLabelText,
fullWidth,
hintStyle,
hintText,
fullWidth,
errorText,
onFocus,
iconStyle,
id,
labelStyle,
onBlur,
onChange,
selectFieldRoot,
style,
tabIndex,
underlineDisabledStyle,
underlineFocusStyle,
underlineStyle,
value,
...other,
} = this.props;

const styles = getStyles(this.props, this.state);
const {
isFocused,
} = this.state;

const {open, muiTheme} = this.state;
const errorStylePrepared = Object.assign({}, errorStyle, {position: 'absolute', bottom: -10});
const floatingLabelStylePrepared = Object.assign({}, floatingLabelStyle, {cursor: 'pointer'});
// ^^^^^^^^^^^^^^^^^
// current implementation
// doesn't do this, but should
let displayValue = '';
React.Children.forEach(children, (child) => {
if (value === child.props.value) {
// This will need to be improved (in case primaryText is a node)
displayValue = child.props.label || child.props.primaryText;
}
});
/* eslint-disable */
console.log(open)
const selecter = (
<SelectFieldLabel
disabled={disabled}
muiTheme={muiTheme}
onBlur={this.onBlur}
onFocus={this.onFocus}
onKeyDown={this.handleKeyDown}
onTouchTap={this.handleTouchTap}
ref={(c) => this.label = ReactDom.findDOMNode(c)}
style={labelStyle}
value={displayValue}
/>
);

const menu = (
<SelectFieldMenu
{...other}
anchorEl={this.label}
autoWidth={autoWidth}
floatingLabelText={floatingLabelText}
onChange={onChange}
onRequestClose={this.handleMenuRequestClose}
open={open}
value={value}
>
{children}
</SelectFieldMenu>
);

return (
<TextField
style={style}
<TextFieldDecorator
disabled={disabled}
errorStyle={errorStylePrepared}
errorText={errorText}
floatingLabelStyle={floatingLabelStylePrepared}
floatingLabelText={floatingLabelText}
floatingLabelStyle={floatingLabelStyle}
fullWidth={fullWidth}
hasValue={true}
height={24}
hintStyle={hintStyle}
hintText={(!hintText && !floatingLabelText) ? ' ' : hintText}
fullWidth={fullWidth}
errorText={errorText}
underlineStyle={underlineStyle}
errorStyle={errorStyle}
onFocus={onFocus}
onBlur={onBlur}
id={id}
isFocused={isFocused}
muiTheme={muiTheme}
style={style}
tabIndex={tabIndex}
underlineDisabledStyle={underlineDisabledStyle}
underlineFocusStyle={underlineFocusStyle}
underlineStyle={underlineStyle}
>
<DropDownMenu
disabled={disabled}
style={selectFieldRoot}
labelStyle={Object.assign(styles.label, labelStyle)}
iconStyle={Object.assign(styles.icon, iconStyle)}
underlineStyle={styles.hideDropDownUnderline}
autoWidth={autoWidth}
value={value}
onChange={onChange}
{...other}
>
{children}
</DropDownMenu>
</TextField>
{selecter}
{menu}
</TextFieldDecorator>
);
},
});
Expand Down

0 comments on commit f0b7887

Please sign in to comment.