Migrate input to themr
parent
40be14660f
commit
243644c144
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ClassNames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
import { themr } from 'react-css-themr';
|
||||||
import FontIcon from '../font_icon';
|
import FontIcon from '../font_icon';
|
||||||
import style from './style';
|
|
||||||
|
|
||||||
class Input extends React.Component {
|
class Input extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -23,6 +23,20 @@ class Input extends React.Component {
|
||||||
onFocus: React.PropTypes.func,
|
onFocus: React.PropTypes.func,
|
||||||
onKeyPress: React.PropTypes.func,
|
onKeyPress: React.PropTypes.func,
|
||||||
required: React.PropTypes.bool,
|
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,
|
type: React.PropTypes.string,
|
||||||
value: React.PropTypes.any
|
value: React.PropTypes.any
|
||||||
};
|
};
|
||||||
|
@ -52,22 +66,22 @@ class Input extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
const { children, disabled, error, floating, hint, icon,
|
const { children, disabled, error, floating, hint, icon,
|
||||||
label: labelText, maxLength, multiline, required,
|
label: labelText, maxLength, multiline, required,
|
||||||
type, value, ...others} = this.props;
|
theme, type, value, ...others} = this.props;
|
||||||
const length = maxLength && value ? value.length : 0;
|
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, {
|
const className = classnames(theme.input, {
|
||||||
[style.disabled]: disabled,
|
[theme.disabled]: disabled,
|
||||||
[style.errored]: error,
|
[theme.errored]: error,
|
||||||
[style.hidden]: type === 'hidden',
|
[theme.hidden]: type === 'hidden',
|
||||||
[style.withIcon]: icon
|
[theme.withIcon]: icon
|
||||||
}, this.props.className);
|
}, this.props.className);
|
||||||
|
|
||||||
const valuePresent = value !== null && value !== undefined && value !== '' && !Number.isNaN(value);
|
const valuePresent = value !== null && value !== undefined && value !== '' && !Number.isNaN(value);
|
||||||
|
|
||||||
const InputElement = React.createElement(multiline ? 'textarea' : 'input', {
|
const InputElement = React.createElement(multiline ? 'textarea' : 'input', {
|
||||||
...others,
|
...others,
|
||||||
className: ClassNames(style.input, {[style.filled]: valuePresent}),
|
className: classnames(theme.inputElement, {[theme.filled]: valuePresent}),
|
||||||
onChange: this.handleChange,
|
onChange: this.handleChange,
|
||||||
ref: 'input',
|
ref: 'input',
|
||||||
role: 'input',
|
role: 'input',
|
||||||
|
@ -81,21 +95,21 @@ class Input extends React.Component {
|
||||||
return (
|
return (
|
||||||
<div data-react-toolbox='input' className={className}>
|
<div data-react-toolbox='input' className={className}>
|
||||||
{InputElement}
|
{InputElement}
|
||||||
{icon ? <FontIcon className={style.icon} value={icon} /> : null}
|
{icon ? <FontIcon className={theme.icon} value={icon} /> : null}
|
||||||
<span className={style.bar}></span>
|
<span className={theme.bar}></span>
|
||||||
{labelText
|
{labelText
|
||||||
? <label className={labelClassName}>
|
? <label className={labelClassName}>
|
||||||
{labelText}
|
{labelText}
|
||||||
{required ? <span className={style.required}> * </span> : null}
|
{required ? <span className={theme.required}> * </span> : null}
|
||||||
</label>
|
</label>
|
||||||
: null}
|
: null}
|
||||||
{hint ? <span className={style.hint}>{hint}</span> : null}
|
{hint ? <span className={theme.hint}>{hint}</span> : null}
|
||||||
{error ? <span className={style.error}>{error}</span> : null}
|
{error ? <span className={theme.error}>{error}</span> : null}
|
||||||
{maxLength ? <span className={style.counter}>{length}/{maxLength}</span> : null}
|
{maxLength ? <span className={theme.counter}>{length}/{maxLength}</span> : null}
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Input;
|
export default themr('ToolboxInput')(Input);
|
||||||
|
|
|
@ -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|
|
| `type` | `String` | `text` | Type of the input element. It can be a valid HTML5 input type|
|
||||||
| `value` | `Any` | | Current value of the input element.|
|
| `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.
|
| Name | Description|
|
||||||
- `focus` to focus the input field.
|
|:-----------|:-----------|
|
||||||
|
| `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.|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@import "../base";
|
@import "../base";
|
||||||
@import "./config";
|
@import "./config";
|
||||||
|
|
||||||
.root {
|
.input {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: $input-padding 0;
|
padding: $input-padding 0;
|
||||||
&.withIcon {
|
&.withIcon {
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
transition: color $animation-duration $animation-curve-default;
|
transition: color $animation-duration $animation-curve-default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.inputElement {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: $input-field-padding 0;
|
padding: $input-field-padding 0;
|
||||||
|
@ -126,14 +126,14 @@
|
||||||
color: $input-text-label-color;
|
color: $input-text-label-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.disabled > .input {
|
.disabled > .inputElement {
|
||||||
color: $input-text-disabled-text-color;
|
color: $input-text-disabled-text-color;
|
||||||
border-bottom-style: dotted;
|
border-bottom-style: dotted;
|
||||||
}
|
}
|
||||||
|
|
||||||
.errored {
|
.errored {
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
> .input {
|
> .inputElement {
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
border-bottom-color: $input-text-error-color;
|
border-bottom-color: $input-text-error-color;
|
||||||
}
|
}
|
|
@ -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='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='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.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='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={<span>J</span>} />
|
<Input type='text' value={this.state.withHintCustomIcon} label='With Hint Text Icon' hint='Hint Text' onChange={this.handleChange.bind(this, 'withHintCustomIcon')} icon='share' />
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue