Skip to content

Commit 53d003b

Browse files
authored
Merge pull request #990 from Shopify/985-textfield-focus
[TextField] Fix `focused` prop so it triggers focus state
2 parents 9dd2ce4 + 0a8266e commit 53d003b

File tree

3 files changed

+52
-17
lines changed

3 files changed

+52
-17
lines changed

UNRELEASED.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f
1414

1515
### Bug fixes
1616

17+
- Fixed the `focused` prop on `TextField` so it sets the focus state ([#990](https://github.com/Shopify/polaris-react/pull/990))
1718
- Resolved an unsupported `React.Fragment` syntax ([#1080](https://github.com/Shopify/polaris-react/pull/1080))
1819
- Constrained `DropZone` height based on inherited wrapper height [#908](https://github.com/Shopify/polaris-react/pull/908)
1920

src/components/TextField/TextField.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,18 +133,26 @@ class TextField extends React.PureComponent<CombinedProps, State> {
133133

134134
this.state = {
135135
height: null,
136-
focus: false,
136+
focus: props.focused || false,
137137
id: props.id || getUniqueID(),
138138
};
139139
}
140140

141-
componentDidUpdate({focused}: CombinedProps) {
142-
if (
143-
this.input &&
144-
focused !== this.props.focused &&
145-
this.props.focused === true
146-
) {
141+
componentDidMount() {
142+
if (!this.props.focused) {
143+
return;
144+
}
145+
146+
this.input.focus();
147+
}
148+
149+
componentDidUpdate({focused: wasFocused}: CombinedProps) {
150+
const {focused} = this.props;
151+
152+
if (!wasFocused && focused) {
147153
this.input.focus();
154+
} else if (wasFocused && !focused) {
155+
this.input.blur();
148156
}
149157
}
150158

src/components/TextField/tests/TextField.test.tsx

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,6 @@ describe('<TextField />', () => {
5858
expect(input.prop('prefix')).toBeUndefined();
5959
});
6060

61-
it('focuses input and calls onFocus() when focused prop has been updated to true', () => {
62-
const element = mountWithAppProvider(
63-
<TextField label="TextField" onChange={noop} />,
64-
);
65-
element.setProps({focused: true});
66-
expect(element.getDOMNode().querySelector('input')).toBe(
67-
document.activeElement,
68-
);
69-
});
70-
7161
describe('onChange()', () => {
7262
it('is called with the new value', () => {
7363
const spy = jest.fn();
@@ -143,6 +133,42 @@ describe('<TextField />', () => {
143133
});
144134
});
145135

136+
describe('focused', () => {
137+
it('input is in focus state if focused is true', () => {
138+
const element = mountWithAppProvider(
139+
<TextField label="TextField" onChange={noop} focused />,
140+
);
141+
142+
expect(element.getDOMNode().querySelector('input')).toBe(
143+
document.activeElement,
144+
);
145+
});
146+
147+
it('focuses input if focused is toggled', () => {
148+
const element = mountWithAppProvider(
149+
<TextField label="TextField" onChange={noop} />,
150+
);
151+
152+
element.setProps({focused: true});
153+
154+
expect(element.getDOMNode().querySelector('input')).toBe(
155+
document.activeElement,
156+
);
157+
});
158+
159+
it('blurs input if focused is toggled', () => {
160+
const element = mountWithAppProvider(
161+
<TextField label="TextField" onChange={noop} focused />,
162+
);
163+
164+
element.setProps({focused: false});
165+
166+
expect(element.getDOMNode().querySelector('input')).not.toBe(
167+
document.activeElement,
168+
);
169+
});
170+
});
171+
146172
describe('autoComplete', () => {
147173
it('defaults to no autoComplete attribute', () => {
148174
const textField = shallowWithAppProvider(

0 commit comments

Comments
 (0)