Skip to content

Commit d8ad586

Browse files
authored
Support rendering leading Icon to TextField (#815)
* support rendering TextField leading Icon * Don't allow rendering prefix or leadingIcon with floatingPlaceholder * remove empty lines * Remove call for unimplemented onLeadingIconLayout * remove tab
1 parent d83cc6c commit d8ad586

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

demo/src/screens/componentScreens/TextFieldScreen/BasicTextFieldScreen.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {Component} from 'react';
22
import {ScrollView} from 'react-native';
3-
import {Colors, View, Text, TextField, Slider, ColorPalette} from 'react-native-ui-lib'; //eslint-disable-line
3+
import {Assets, Spacings, View, Text, TextField} from 'react-native-ui-lib'; //eslint-disable-line
44

55
import {
66
renderBooleanOption,
@@ -21,13 +21,19 @@ const GUIDING_TEXTS = {
2121
floatingPlaceholder: 'Floating Placeholder'
2222
};
2323

24+
const LEADING_ICON = {
25+
source: Assets.icons.demo.search,
26+
style: {marginRight: Spacings.s1}
27+
};
28+
2429
export default class BasicTextFieldScreen extends Component {
2530
constructor(props) {
2631
super(props);
2732

2833
this.state = {
2934
hideUnderline: false,
3035
withPrefix: false,
36+
withLeadingIcon: false,
3137
underlineColor: undefined,
3238
guidingText: GUIDING_TEXTS.none,
3339
disabled: false,
@@ -45,6 +51,7 @@ export default class BasicTextFieldScreen extends Component {
4551
const {
4652
hideUnderline,
4753
withPrefix,
54+
withLeadingIcon,
4855
underlineColor,
4956
guidingText,
5057
titleColor,
@@ -67,6 +74,7 @@ export default class BasicTextFieldScreen extends Component {
6774
hideUnderline={hideUnderline}
6875
underlineColor={underlineColor}
6976
prefix={withPrefix ? 'prefix://' : undefined}
77+
leadingIcon={withLeadingIcon ? LEADING_ICON : undefined}
7078
title={guidingText === GUIDING_TEXTS.useTitle ? 'Title' : undefined}
7179
titleColor={titleColor}
7280
floatingPlaceholder={guidingText === GUIDING_TEXTS.floatingPlaceholder}
@@ -98,6 +106,7 @@ export default class BasicTextFieldScreen extends Component {
98106
{renderBooleanOption.call(this, 'Centered', 'centered')}
99107
{renderBooleanOption.call(this, 'Hide Underline', 'hideUnderline')}
100108
{renderBooleanOption.call(this, 'With Prefix', 'withPrefix')}
109+
{renderBooleanOption.call(this, 'With leadingIcon', 'withLeadingIcon')}
101110
{renderColorOption.call(this, 'Underline Color', 'underlineColor')}
102111
{renderRadioGroup.call(this, 'Guiding Text', 'guidingText', GUIDING_TEXTS)}
103112
{renderColorOption.call(this, 'Title Color', 'titleColor')}
@@ -109,4 +118,3 @@ export default class BasicTextFieldScreen extends Component {
109118
);
110119
}
111120
}
112-

src/components/inputs/TextField.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export default class TextField extends BaseInput {
125125
*/
126126
transformer: PropTypes.func,
127127
/**
128-
* Pass to render a prefix text as part of the input
128+
* Pass to render a prefix text as part of the input (doesn't work with floatingPlaceholder)
129129
*/
130130
prefix: PropTypes.string,
131131
/**
@@ -172,7 +172,11 @@ export default class TextField extends BaseInput {
172172
iconColor: PropTypes.string,
173173
onPress: PropTypes.func,
174174
style: PropTypes.oneOfType([PropTypes.object, PropTypes.number])
175-
})
175+
}),
176+
/**
177+
* Pass to render a leading icon to the TextInput value. Accepts Image props (doesn't work with floatingPlaceholder)
178+
*/
179+
leadingIcon: PropTypes.shape(Image.propTypes)
176180
};
177181

178182
static defaultProps = {
@@ -310,8 +314,7 @@ export default class TextField extends BaseInput {
310314
}
311315

312316
getTopPaddings() {
313-
const {floatingPlaceholder} = this.getThemeProps();
314-
return floatingPlaceholder ? (this.shouldShowTopError() ? undefined : 25) : undefined;
317+
return this.shouldFakePlaceholder() ? (this.shouldShowTopError() ? undefined : 25) : undefined;
315318
}
316319

317320
isDisabled() {
@@ -345,8 +348,9 @@ export default class TextField extends BaseInput {
345348
}
346349

347350
shouldFakePlaceholder() {
348-
const {floatingPlaceholder, centered} = this.getThemeProps();
349-
return Boolean(floatingPlaceholder && !centered && !this.shouldShowTopError());
351+
const {floatingPlaceholder, centered, leadingIcon, prefix} = this.getThemeProps();
352+
353+
return !leadingIcon && !prefix && Boolean(floatingPlaceholder && !centered && !this.shouldShowTopError());
350354
}
351355

352356
shouldShowError() {
@@ -389,6 +393,9 @@ export default class TextField extends BaseInput {
389393
style={[
390394
this.styles.placeholder,
391395
typography,
396+
// TODO: we need to exclude completely any dependency on line height
397+
// in this component since it always breaks alignments
398+
{lineHeight: undefined},
392399
{
393400
transform: [
394401
{
@@ -627,7 +634,7 @@ export default class TextField extends BaseInput {
627634
}
628635

629636
render() {
630-
const {expandable, containerStyle, underlineColor, useTopErrors, hideUnderline} = this.getThemeProps();
637+
const {expandable, containerStyle, underlineColor, useTopErrors, hideUnderline, leadingIcon} = this.getThemeProps();
631638
const underlineStateColor = this.getStateColor(underlineColor || UNDERLINE_COLOR_BY_STATE);
632639

633640
return (
@@ -642,6 +649,7 @@ export default class TextField extends BaseInput {
642649
{paddingTop: this.getTopPaddings()}
643650
]}
644651
>
652+
{leadingIcon && <Image {...leadingIcon}/>}
645653
{this.renderPrefix()}
646654
{this.renderPlaceholder()}
647655
{expandable ? this.renderExpandableInput() : this.renderTextInput()}

0 commit comments

Comments
 (0)