Skip to content
This repository was archived by the owner on Dec 23, 2022. It is now read-only.

Commit 804c615

Browse files
committed
Add support for a floating label.
Resolves #3.
1 parent 275e4c6 commit 804c615

File tree

2 files changed

+80
-19
lines changed

2 files changed

+80
-19
lines changed

src/ChipInput.js

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import React from 'react'
66
import TextFieldUnderline from 'material-ui/TextField/TextFieldUnderline'
77
import TextFieldHint from 'material-ui/TextField/TextFieldHint'
8+
import TextFieldLabel from 'material-ui/TextField/TextFieldLabel'
89
import AutoComplete from 'material-ui/AutoComplete/AutoComplete'
910
import transitions from 'material-ui/styles/transitions'
1011
import Chip from 'material-ui/Chip'
@@ -29,7 +30,6 @@ const getStyles = (props, context, state) => {
2930
fontSize: 16,
3031
lineHeight: '24px',
3132
width: props.fullWidth ? '100%' : 256,
32-
height: (props.rows - 1) * 24 + (props.floatingLabelText ? 72 : 48),
3333
display: 'inline-block',
3434
position: 'relative',
3535
backgroundColor: backgroundColor,
@@ -54,16 +54,28 @@ const getStyles = (props, context, state) => {
5454
appearance: 'textfield', // Improve type search style.
5555
WebkitTapHighlightColor: 'rgba(0,0,0,0)', // Remove mobile color flashing (deprecated style).
5656
float: 'left',
57+
},
58+
floatingLabel: {
59+
color: hintColor,
60+
pointerEvents: 'none',
61+
top: 28
62+
},
63+
floatingLabelFocusStyle: {
64+
transform: 'scale(0.75) translate(0, -36px)'
5765
}
5866
};
5967

68+
if (state.hasValue) {
69+
styles.floatingLabel.color = fade(props.disabled ? disabledTextColor : floatingLabelColor, 0.5);
70+
}
71+
72+
if (state.isFocused) {
73+
styles.floatingLabel.color = focusColor;
74+
}
75+
6076
if (props.floatingLabelText) {
6177
styles.input.boxSizing = 'border-box';
6278

63-
if (!props.multiLine) {
64-
styles.input.marginTop = 14;
65-
}
66-
6779
if (state.errorText) {
6880
styles.error.bottom = !props.multiLine ? styles.error.fontSize + 3 : 3;
6981
}
@@ -99,6 +111,18 @@ class ChipInput extends React.Component {
99111
}
100112
}
101113

114+
componentWillMount() {
115+
const {
116+
name,
117+
hintText,
118+
floatingLabelText
119+
} = this.props;
120+
121+
const uniqueId = `${name}-${hintText}-${floatingLabelText}-${
122+
Math.floor(Math.random() * 0xFFFF)}`;
123+
this.uniqueId = uniqueId.replace(/[^A-Za-z0-9-]/gi, '');
124+
}
125+
102126
blur() {
103127
if (this.input) this.getInputNode().blur();
104128
}
@@ -234,42 +258,69 @@ class ChipInput extends React.Component {
234258
defaultValue = [],
235259
value,
236260
dataSource,
261+
floatingLabelFixed,
262+
floatingLabelFocusStyle, // eslint-disable-line no-unused-vars
263+
floatingLabelStyle, // eslint-disable-line no-unused-vars
264+
floatingLabelText,
237265
...other,
238266
} = this.props;
239267

268+
const {prepareStyles} = this.context.muiTheme;
269+
const styles = getStyles(this.props, this.context, this.state);
270+
const inputId = this.uniqueId;
271+
240272
const inputProps = {
273+
id: inputId,
241274
ref: (elem) => this.input = elem,
242275
disabled: this.props.disabled,
243276
onBlur: this.handleInputBlur,
244277
onFocus: this.handleInputFocus,
245278
onKeyDown: this.handleKeyDown
246279
}
247280

248-
const styles = getStyles(this.props, this.context, this.state);
249-
const {prepareStyles} = this.context.muiTheme;
250281
const inputStyleMerged = Object.assign(styles.input, inputStyle);
251282

283+
const showHintText = hintText && (this.props.value || this.state.chips).length === 0 && this.state.inputValue.length === 0
284+
285+
const floatingLabelTextElement = floatingLabelText && (
286+
<TextFieldLabel
287+
muiTheme={this.context.muiTheme}
288+
style={Object.assign(styles.floatingLabel, this.props.floatingLabelStyle)}
289+
shrinkStyle={Object.assign(styles.floatingLabelFocusStyle, this.props.floatingLabelFocusStyle)}
290+
htmlFor={inputId}
291+
shrink={!showHintText || this.state.isFocused}
292+
disabled={disabled}
293+
>
294+
{floatingLabelText}
295+
</TextFieldLabel>
296+
)
297+
298+
const shrinkFloatingLabel = floatingLabelText && (!showHintText || this.state.isFocused)
299+
252300
return (
253301
<div
254302
style={prepareStyles(Object.assign(styles.root, style))}
255303
onTouchTap={() => this.focus()}
256304
>
257-
<div>
258-
{(this.props.value || this.state.chips).map((tag) => (
259-
<Chip
260-
style={{ margin: '8px 8px 0 0', float: 'left' }}
261-
backgroundColor={this.state.focusedChip === tag ? blue300 : null}
262-
onTouchTap={() => { this.setState({ focusedChip: tag }) }}
263-
onRequestDelete={() => this.handleDeleteChip(tag)}
264-
>
265-
{tag}
266-
</Chip>
267-
))}
305+
<div>
306+
{floatingLabelTextElement}
307+
<div style={{ marginTop: floatingLabelText ? 12 : 0 }}>
308+
{(this.props.value || this.state.chips).map((tag) => (
309+
<Chip
310+
style={{ margin: '8px 8px 0 0', float: 'left' }}
311+
backgroundColor={this.state.focusedChip === tag ? blue300 : null}
312+
onTouchTap={() => { this.setState({ focusedChip: tag }) }}
313+
onRequestDelete={() => this.handleDeleteChip(tag)}
314+
>
315+
{tag}
316+
</Chip>
317+
))}
318+
</div>
268319
</div>
269320
{hintText ?
270321
<TextFieldHint
271322
muiTheme={this.context.muiTheme}
272-
show={(this.props.value || this.state.chips).length === 0 && this.state.inputValue.length === 0}
323+
show={showHintText && !(floatingLabelText && !this.state.isFocused)}
273324
style={Object.assign({ bottom: 20, pointerEvents: 'none' }, hintStyle)}
274325
text={hintText}
275326
/> :

stories/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ storiesOf('ChipInput', module)
4242
/>
4343
</MuiThemeProvider>
4444
))
45+
.add('with floating label', () => (
46+
<MuiThemeProvider muiTheme={getMuiTheme(lightBaseTheme)}>
47+
<ChipInput
48+
defaultValue={['foo', 'bar']}
49+
floatingLabelText="Some chips"
50+
hintText="Try typing a..."
51+
style={{ width: '100%' }}
52+
/>
53+
</MuiThemeProvider>
54+
))
4555
.add('controlled input', () => (
4656
<MuiThemeProvider muiTheme={getMuiTheme(lightBaseTheme)}>
4757
<ControlledChipInput />

0 commit comments

Comments
 (0)