Skip to content

Commit e213fe2

Browse files
authored
feat: triggerFocus support (#709)
1 parent 7558cb8 commit e213fe2

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

src/Dom/focus.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,43 @@ export function limitTabRange(node: HTMLElement, e: KeyboardEvent) {
9797
}
9898
}
9999
}
100+
101+
export interface InputFocusOptions extends FocusOptions {
102+
cursor?: 'start' | 'end' | 'all';
103+
}
104+
105+
// Used for `rc-input` `rc-textarea` `rc-input-number`
106+
/**
107+
* Focus element and set cursor position for input/textarea elements.
108+
*/
109+
export function triggerFocus(
110+
element?: HTMLElement,
111+
option?: InputFocusOptions,
112+
) {
113+
if (!element) return;
114+
115+
element.focus(option);
116+
117+
// Selection content
118+
const { cursor } = option || {};
119+
if (
120+
cursor &&
121+
(element instanceof HTMLInputElement ||
122+
element instanceof HTMLTextAreaElement)
123+
) {
124+
const len = element.value.length;
125+
126+
switch (cursor) {
127+
case 'start':
128+
element.setSelectionRange(0, 0);
129+
break;
130+
131+
case 'end':
132+
element.setSelectionRange(len, len);
133+
break;
134+
135+
default:
136+
element.setSelectionRange(0, len);
137+
}
138+
}
139+
}

tests/focus.test.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable class-methods-use-this */
22
import { spyElementPrototype } from '../src/test/domHook';
3-
import { getFocusNodeList } from '../src/Dom/focus';
3+
import { getFocusNodeList, triggerFocus } from '../src/Dom/focus';
44

55
describe('focus', () => {
66
beforeAll(() => {
@@ -31,4 +31,29 @@ describe('focus', () => {
3131
const tabFocusList = getFocusNodeList(div, true);
3232
expect(tabFocusList).toHaveLength(5);
3333
});
34+
35+
it('triggerFocus should set cursor position for textarea', () => {
36+
const textarea = document.createElement('textarea');
37+
textarea.value = 'test content';
38+
39+
const focusSpy = jest.spyOn(textarea, 'focus');
40+
const setSelectionRangeSpy = jest.spyOn(textarea, 'setSelectionRange');
41+
42+
// Test cursor: 'start'
43+
triggerFocus(textarea, { cursor: 'start' });
44+
expect(setSelectionRangeSpy).toHaveBeenCalledWith(0, 0);
45+
46+
// Test cursor: 'end'
47+
triggerFocus(textarea, { cursor: 'end' });
48+
expect(setSelectionRangeSpy).toHaveBeenCalledWith(12, 12); // 'test content'.length = 12
49+
50+
// Test cursor: 'all'
51+
triggerFocus(textarea, { cursor: 'all' });
52+
expect(setSelectionRangeSpy).toHaveBeenCalledWith(0, 12); // select all text
53+
54+
expect(focusSpy).toHaveBeenCalledTimes(3);
55+
56+
focusSpy.mockRestore();
57+
setSelectionRangeSpy.mockRestore();
58+
});
3459
});

0 commit comments

Comments
 (0)