Skip to content

Commit

Permalink
fix: fixed autoFocus bug in Input and TextArea #2193
Browse files Browse the repository at this point in the history
  • Loading branch information
shijiame committed Apr 22, 2024
1 parent 933e2bf commit 9733059
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 35 deletions.
11 changes: 11 additions & 0 deletions cypress/e2e/input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,15 @@ describe('input', () => {
cy.get('body').click();
cy.get('.semi-input-wrapper').eq(2).children('input').should('not.be.focused');
});

it('input autofocus should focus to text end', () => {
cy.visit('http://localhost:6006/iframe.html?args=&id=input--fix-input-auto-focus&viewMode=story');
cy.wait(300);
cy.window().then(window => {
const inputStr = window.document.body.querySelector('.semi-input').value.length;
const count = inputStr.length;
cy.get('div[data-cy=start]').should('contain.text', inputStr);
cy.get('div[data-cy=end]').should('contain.text', inputStr);
});
});
});
6 changes: 6 additions & 0 deletions cypress/e2e/textarea.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,10 @@ describe('textarea', () => {
expect(scrollHeight).eq(clientHeight);
});
});

it('textarea autofocus should focus to text end', () => {
cy.visit('http://localhost:6006/iframe.html?args=&id=input--fix-text-area-auto-focus&viewMode=story');
cy.get('div[data-cy=start]').should('contain.text', 0);
cy.get('div[data-cy=end]').should('contain.text', 0);
});
});
14 changes: 0 additions & 14 deletions packages/semi-foundation/input/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ class InputFoundation extends BaseFoundation<InputAdapter> {
super({ ...InputFoundation.inputDefaultAdapter, ...adapter });
}

init() {
this._setInitValue();
}

destroy() {
if (this._timer) {
clearTimeout(this._timer);
Expand All @@ -53,16 +49,6 @@ class InputFoundation extends BaseFoundation<InputAdapter> {

setDisable() {}

_setInitValue() {
const { defaultValue, value } = this.getProps();
let v = defaultValue;
if (this._isControlledComponent()) {
v = value;
}
this._adapter.setValue(v);
// this.checkAllowClear(v);
}

setValue(value: any) {
this._adapter.setValue(value);
}
Expand Down
16 changes: 0 additions & 16 deletions packages/semi-foundation/input/textareaFoundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,8 @@ export default class TextAreaFoundation extends BaseFoundation<TextAreaAdapter>
});
}

init() {
this.setInitValue();
}

destroy() { }

setInitValue() {
const {
defaultValue,
value
} = this.getProps();
let v = defaultValue;
if (this._isControlledComponent()) {
v = value;
}
this._adapter.setValue(v);
}

handleValueChange(v: string) {
this._adapter.setValue(v);
}
Expand Down
39 changes: 38 additions & 1 deletion packages/semi-ui/input/_story/input.stories.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useCallback, useRef } from 'react';
import React, { useState, useCallback, useRef, useEffect } from 'react';
import GraphemeSplitter from 'grapheme-splitter';
import { isFunction, isString } from 'lodash';

Expand Down Expand Up @@ -1031,3 +1031,40 @@ export const TextAutoSizeResize = () => {
</div>
)
};

export const FixInputAutoFocus = () => {
const longStr = 'semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design';
const inputRef = useRef();
const [selection, setSelection] = useState();
useEffect(() => {
const start = inputRef.current.selectionStart;
const end = inputRef.current.selectionEnd;
setSelection({ start, end, length: longStr.length });
}, []);
return (
<div>
<Input ref={inputRef} style={{ width: 200 }} autoFocus defaultValue={longStr} />
<div data-cy="start">start: {selection?.start}</div>
<div data-cy="end">end: {selection?.end}</div>
</div>
)
};

export const FixTextAreaAutoFocus = () => {
const inputRef = useRef();
const [selection, setSelection] = useState();
useEffect(() => {
const start = inputRef.current.selectionStart;
const end = inputRef.current.selectionEnd;
setSelection({ start, end });
}, []);
const longStr = 'semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design semi design';
return (
<div>
<TextArea ref={inputRef} style={{ width: 200 }} autoFocus defaultValue={longStr} />
<div data-cy="start">start: {selection?.start}</div>
<div data-cy="end">end: {selection?.end}</div>
</div>
)
};

6 changes: 3 additions & 3 deletions packages/semi-ui/input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,10 @@ class Input extends BaseComponent<InputProps, InputState> {

constructor(props: InputProps) {
super(props);
const initValue = 'value' in props ? props.value : props.defaultValue;
this.state = {
value: '',
cachedValue: null, // Cache current props.value value
value: initValue,
cachedValue: props.value, // Cache current props.value value
disabled: false,
props: {},
isFocus: false,
Expand Down Expand Up @@ -223,7 +224,6 @@ class Input extends BaseComponent<InputProps, InputState> {
componentDidMount(): void {
// autofocus is changed from the original support of input to the support of manually calling the focus method,
// so that preventScroll can still take effect under the setting of autofocus
this.foundation.init();
const { disabled, autoFocus, preventScroll } = this.props;
if (!disabled && (autoFocus || this.props['autofocus'])) {
this.inputRef.current.focus({ preventScroll });
Expand Down
4 changes: 3 additions & 1 deletion packages/semi-ui/input/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,14 @@ class TextArea extends BaseComponent<TextAreaProps, TextAreaState> {

constructor(props: TextAreaProps) {
super(props);
const initValue = 'value' in props ? props.value : props.defaultValue;
this.state = {
value: '',
value: initValue,
isFocus: false,
isHover: false,
height: 0,
minLength: props.minLength,
cachedValue: props.value,
};
this.focusing = false;
this.foundation = new TextAreaFoundation(this.adapter);
Expand Down

0 comments on commit 9733059

Please sign in to comment.