Migrate input to themr

old
Javi Velasco 2016-05-21 18:57:49 +02:00
parent 40be14660f
commit 243644c144
4 changed files with 53 additions and 27 deletions

View File

@ -1,7 +1,7 @@
import React from 'react';
import ClassNames from 'classnames';
import classnames from 'classnames';
import { themr } from 'react-css-themr';
import FontIcon from '../font_icon';
import style from './style';
class Input extends React.Component {
static propTypes = {
@ -23,6 +23,20 @@ class Input extends React.Component {
onFocus: React.PropTypes.func,
onKeyPress: React.PropTypes.func,
required: React.PropTypes.bool,
theme: React.PropTypes.shape({
bar: React.PropTypes.string.isRequired,
counter: React.PropTypes.string.isRequired,
disabled: React.PropTypes.string.isRequired,
error: React.PropTypes.string.isRequired,
errored: React.PropTypes.string.isRequired,
hidden: React.PropTypes.string.isRequired,
hint: React.PropTypes.string.isRequired,
icon: React.PropTypes.string.isRequired,
input: React.PropTypes.string.isRequired,
inputElement: React.PropTypes.string.isRequired,
required: React.PropTypes.string.isRequired,
withIcon: React.PropTypes.string.isRequired
}),
type: React.PropTypes.string,
value: React.PropTypes.any
};
@ -52,22 +66,22 @@ class Input extends React.Component {
render () {
const { children, disabled, error, floating, hint, icon,
label: labelText, maxLength, multiline, required,
type, value, ...others} = this.props;
theme, type, value, ...others} = this.props;
const length = maxLength && value ? value.length : 0;
const labelClassName = ClassNames(style.label, {[style.fixed]: !floating});
const labelClassName = classnames(theme.label, {[theme.fixed]: !floating});
const className = ClassNames(style.root, {
[style.disabled]: disabled,
[style.errored]: error,
[style.hidden]: type === 'hidden',
[style.withIcon]: icon
const className = classnames(theme.input, {
[theme.disabled]: disabled,
[theme.errored]: error,
[theme.hidden]: type === 'hidden',
[theme.withIcon]: icon
}, this.props.className);
const valuePresent = value !== null && value !== undefined && value !== '' && !Number.isNaN(value);
const InputElement = React.createElement(multiline ? 'textarea' : 'input', {
...others,
className: ClassNames(style.input, {[style.filled]: valuePresent}),
className: classnames(theme.inputElement, {[theme.filled]: valuePresent}),
onChange: this.handleChange,
ref: 'input',
role: 'input',
@ -81,21 +95,21 @@ class Input extends React.Component {
return (
<div data-react-toolbox='input' className={className}>
{InputElement}
{icon ? <FontIcon className={style.icon} value={icon} /> : null}
<span className={style.bar}></span>
{icon ? <FontIcon className={theme.icon} value={icon} /> : null}
<span className={theme.bar}></span>
{labelText
? <label className={labelClassName}>
{labelText}
{required ? <span className={style.required}> * </span> : null}
{required ? <span className={theme.required}> * </span> : null}
</label>
: null}
{hint ? <span className={style.hint}>{hint}</span> : null}
{error ? <span className={style.error}>{error}</span> : null}
{maxLength ? <span className={style.counter}>{length}/{maxLength}</span> : null}
{hint ? <span className={theme.hint}>{hint}</span> : null}
{error ? <span className={theme.error}>{error}</span> : null}
{maxLength ? <span className={theme.counter}>{length}/{maxLength}</span> : null}
{children}
</div>
);
}
}
export default Input;
export default themr('ToolboxInput')(Input);

View File

@ -48,9 +48,21 @@ class InputTest extends React.Component {
| `type` | `String` | `text` | Type of the input element. It can be a valid HTML5 input type|
| `value` | `Any` | | Current value of the input element.|
## Methods
## Theming
The input is stateless but it includes two methods to be able to communicate with the DOM input node:
The input component uses `ToolboxInput` as theme context id and the configuration is available in the `_config.scss` as usual. Here is the class interface:
- `blur` to blur the input field.
- `focus` to focus the input field.
| Name | Description|
|:-----------|:-----------|
| `bar` | Used for the bar under the input.|
| `counter` | Used for the counter element.|
| `disabled` | Added to the root class when input is disabled.|
| `error` | Used for the text error.|
| `errored` | Added to the root class when input is errored.|
| `hidden` | Used when the input is hidden.|
| `hint` | Used for the hint text.|
| `icon` | Used for the icon in case the input has icon.|
| `input` | Used as root class for the component.|
| `inputElement` | Used for the HTML input element.|
| `required` | Used in case the input is required.|
| `withIcon` | Added to the root class if the input has icon.|

View File

@ -1,7 +1,7 @@
@import "../base";
@import "./config";
.root {
.input {
position: relative;
padding: $input-padding 0;
&.withIcon {
@ -23,7 +23,7 @@
transition: color $animation-duration $animation-curve-default;
}
.input {
.inputElement {
display: block;
width: 100%;
padding: $input-field-padding 0;
@ -126,14 +126,14 @@
color: $input-text-label-color;
}
.disabled > .input {
.disabled > .inputElement {
color: $input-text-disabled-text-color;
border-bottom-style: dotted;
}
.errored {
padding-bottom: 0;
> .input {
> .inputElement {
margin-top: 1px;
border-bottom-color: $input-text-error-color;
}

View File

@ -31,8 +31,8 @@ class InputTest extends React.Component {
<Input type='email' value={this.state.multilineHint} label='Description' hint='Enter Description' multiline onChange={this.handleChange.bind(this, 'multilineHint')} />
<Input type='text' label='Disabled field' disabled />
<Input type='tel' value={this.state.withIcon} required label='With icon' onChange={this.handleChange.bind(this, 'withIcon')} icon='phone' />
<Input type='tel' value={this.state.withCustomIcon} label='With custom icon' onChange={this.handleChange.bind(this, 'withCustomIcon')} icon={<span>P</span>} />
<Input type='text' value={this.state.withHintCustomIcon} label='With Hint Text Icon' hint='Hint Text' onChange={this.handleChange.bind(this, 'withHintCustomIcon')} icon={<span>J</span>} />
<Input type='tel' value={this.state.withCustomIcon} label='With custom icon' onChange={this.handleChange.bind(this, 'withCustomIcon')} icon='favorite' />
<Input type='text' value={this.state.withHintCustomIcon} label='With Hint Text Icon' hint='Hint Text' onChange={this.handleChange.bind(this, 'withHintCustomIcon')} icon='share' />
</section>
);
}