Browse Source

Merge pull request #15184 from ant-design/fix-input-focus-state

Fix Input Password focus state
pull/15197/head
偏右 6 years ago
committed by GitHub
parent
commit
5dec4960df
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      components/input/Input.tsx
  2. 21
      components/input/Password.tsx
  3. 2
      components/input/__tests__/__snapshots__/demo.test.js.snap
  4. 9
      components/input/__tests__/__snapshots__/index.test.js.snap
  5. 29
      components/input/__tests__/index.test.js
  6. 2
      components/input/demo/group.md
  7. 2
      components/input/demo/textarea-resize.md

7
components/input/Input.tsx

@ -142,9 +142,10 @@ class Input extends React.Component<InputProps, any> {
setValue(
value: string,
e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLElement, MouseEvent>,
callback?: () => void,
) {
if (!('value' in this.props)) {
this.setState({ value });
this.setState({ value }, callback);
}
const { onChange } = this.props;
if (onChange) {
@ -167,7 +168,9 @@ class Input extends React.Component<InputProps, any> {
}
handleReset = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
this.setValue('', e);
this.setValue('', e, () => {
this.focus();
});
};
handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {

21
components/input/Password.tsx

@ -39,15 +39,18 @@ export default class Password extends React.Component<PasswordProps, PasswordSta
getIcon() {
const { prefixCls, action } = this.props;
const iconTrigger = ActionMap[action] || '';
const iconProps = { [iconTrigger]: this.onChange };
return React.cloneElement(
<Icon
{...iconProps}
className={`${prefixCls}-icon`}
type={this.state.visible ? 'eye-invisible' : 'eye'}
key="passwordIcon"
/>,
);
const iconProps = {
[iconTrigger]: this.onChange,
className: `${prefixCls}-icon`,
type: this.state.visible ? 'eye-invisible' : 'eye',
key: 'passwordIcon',
onMouseDown: (e: MouseEvent) => {
// Prevent focused state lost
// https://github.com/ant-design/ant-design/issues/15173
e.preventDefault();
},
};
return <Icon {...iconProps} />;
}
render() {

2
components/input/__tests__/__snapshots__/demo.test.js.snap

@ -494,6 +494,7 @@ exports[`renders ./components/input/demo/group.md correctly 1`] = `
/>
<span
class="ant-calendar-picker"
style="width:50%"
>
<div>
<input
@ -1144,6 +1145,7 @@ exports[`renders ./components/input/demo/textarea-resize.md correctly 1`] = `
<div>
<button
class="ant-btn"
style="margin-bottom:16px"
type="button"
>
<span>

9
components/input/__tests__/__snapshots__/index.test.js.snap

@ -297,6 +297,7 @@ exports[`Input.Password should change type when click 1`] = `
<Icon
className="ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye"
/>
}
@ -323,6 +324,7 @@ exports[`Input.Password should change type when click 1`] = `
className="ant-input-password-icon"
key="passwordIcon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye"
>
<LocaleReceiver
@ -332,6 +334,7 @@ exports[`Input.Password should change type when click 1`] = `
aria-label="icon: eye"
className="anticon anticon-eye ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
tabIndex={-1}
>
<IconReact
@ -380,6 +383,7 @@ exports[`Input.Password should change type when click 2`] = `
<Icon
className="ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye-invisible"
/>
}
@ -406,6 +410,7 @@ exports[`Input.Password should change type when click 2`] = `
className="ant-input-password-icon"
key="passwordIcon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye-invisible"
>
<LocaleReceiver
@ -415,6 +420,7 @@ exports[`Input.Password should change type when click 2`] = `
aria-label="icon: eye-invisible"
className="anticon anticon-eye-invisible ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
tabIndex={-1}
>
<IconReact
@ -467,6 +473,7 @@ exports[`Input.Password should change type when click 3`] = `
<Icon
className="ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye"
/>
}
@ -493,6 +500,7 @@ exports[`Input.Password should change type when click 3`] = `
className="ant-input-password-icon"
key="passwordIcon"
onClick={[Function]}
onMouseDown={[Function]}
type="eye"
>
<LocaleReceiver
@ -502,6 +510,7 @@ exports[`Input.Password should change type when click 3`] = `
aria-label="icon: eye"
className="anticon anticon-eye ant-input-password-icon"
onClick={[Function]}
onMouseDown={[Function]}
tabIndex={-1}
>
<IconReact

29
components/input/__tests__/index.test.js

@ -201,6 +201,24 @@ describe('Input.Password', () => {
wrapper.setProps({ visibilityToggle: true });
expect(wrapper.find('.anticon-eye').length).toBe(1);
});
it('should keep focus state', () => {
const wrapper = mount(<Input.Password defaultValue="111" autoFocus />);
expect(document.activeElement).toBe(
wrapper.find('input').at(0).getDOMNode()
);
wrapper
.find('.ant-input-password-icon')
.at(0)
.simulate('mousedown');
wrapper
.find('.ant-input-password-icon')
.at(0)
.simulate('click');
expect(document.activeElement).toBe(
wrapper.find('input').at(0).getDOMNode()
);
});
});
describe('Input allowClear', () => {
@ -280,4 +298,15 @@ describe('Input allowClear', () => {
.getDOMNode().value,
).toBe('111');
});
it('should focus input after clear', () => {
const wrapper = mount(<Input allowClear defaultValue="111" />);
wrapper
.find('.ant-input-clear-icon')
.at(0)
.simulate('click');
expect(document.activeElement).toBe(
wrapper.find('input').at(0).getDOMNode()
);
});
});

2
components/input/demo/group.md

@ -102,7 +102,7 @@ class CompactDemo extends React.Component {
<br />
<InputGroup compact>
<Input style={{ width: '50%' }} defaultValue="input content" />
<DatePicker />
<DatePicker style={{ width: '50%' }} />
</InputGroup>
<br />
<InputGroup compact>

2
components/input/demo/textarea-resize.md

@ -31,7 +31,7 @@ class Demo extends React.Component {
return (
<div>
<Button onClick={() => this.setState({ autoResize: !autoResize })}>
<Button onClick={() => this.setState({ autoResize: !autoResize })} style={{ marginBottom: 16 }}>
Auto Resize: {String(autoResize)}
</Button>
<TextArea rows={4} autosize={autoResize} defaultValue={defaultValue} />

Loading…
Cancel
Save