From fca5d5feb81142c2ca45273537a6b5965de6284a Mon Sep 17 00:00:00 2001 From: Gethin Webster Date: Fri, 14 Feb 2025 11:29:14 +0100 Subject: [PATCH] feat: Add setSelectionRange to PromptInput (#3294) --- .../__snapshots__/documenter.test.ts.snap | 23 +++++++++++++++++++ .../__tests__/prompt-input.test.tsx | 17 ++++++++++++++ src/prompt-input/interfaces.ts | 9 ++++++++ src/prompt-input/internal.tsx | 3 +++ 4 files changed, 52 insertions(+) diff --git a/src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap b/src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap index 4a5bad6e2b..fa7fc09682 100644 --- a/src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap +++ b/src/__tests__/snapshot-tests/__snapshots__/documenter.test.ts.snap @@ -12604,6 +12604,29 @@ about modifiers (that is, CTRL, ALT, SHIFT, META, etc.).", "parameters": [], "returnType": "void", }, + { + "description": "Selects a range of text in the textarea control. +See https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement/setSelectionRange +for more details on this method. Be aware that using this method in React has some +common pitfalls: https://stackoverflow.com/questions/60129605/is-javascripts-setselectionrange-incompatible-with-react-hooks +", + "name": "setSelectionRange", + "parameters": [ + { + "name": "start", + "type": "null | number", + }, + { + "name": "end", + "type": "null | number", + }, + { + "name": "direction", + "type": ""backward" | "forward" | "none"", + }, + ], + "returnType": "void", + }, ], "name": "PromptInput", "properties": [ diff --git a/src/prompt-input/__tests__/prompt-input.test.tsx b/src/prompt-input/__tests__/prompt-input.test.tsx index 5ef8280129..f8db96576b 100644 --- a/src/prompt-input/__tests__/prompt-input.test.tsx +++ b/src/prompt-input/__tests__/prompt-input.test.tsx @@ -55,6 +55,23 @@ describe('ref', () => { expect(textarea.selectionStart).toBe(0); expect(textarea.selectionEnd).toBe(4); }); + + test('can be used to select a range', () => { + const ref = React.createRef(); + const { wrapper } = renderPromptInput({ value: 'Test', ref }); + const textarea = wrapper.findNativeTextarea().getElement(); + + // Make sure no text is selected + textarea.selectionStart = textarea.selectionEnd = 0; + textarea.blur(); + expect(textarea.selectionStart).toBe(0); + expect(textarea.selectionEnd).toBe(0); + + // Select all text + ref.current!.setSelectionRange(1, 3); + expect(textarea.selectionStart).toBe(1); + expect(textarea.selectionEnd).toBe(3); + }); }); describe('disableBrowserAutocorrect', () => { diff --git a/src/prompt-input/interfaces.ts b/src/prompt-input/interfaces.ts index e5d47ca872..3dea7b9e42 100644 --- a/src/prompt-input/interfaces.ts +++ b/src/prompt-input/interfaces.ts @@ -119,5 +119,14 @@ export namespace PromptInputProps { * Selects all text in the textarea control. */ select(): void; + + /** + * Selects a range of text in the textarea control. + * + * See https://developer.mozilla.org/en-US/docs/Web/API/HTMLTextAreaElement/setSelectionRange + * for more details on this method. Be aware that using this method in React has some + * common pitfalls: https://stackoverflow.com/questions/60129605/is-javascripts-setselectionrange-incompatible-with-react-hooks + */ + setSelectionRange(start: number | null, end: number | null, direction?: 'forward' | 'backward' | 'none'): void; } } diff --git a/src/prompt-input/internal.tsx b/src/prompt-input/internal.tsx index a4466450e5..205a3cb026 100644 --- a/src/prompt-input/internal.tsx +++ b/src/prompt-input/internal.tsx @@ -77,6 +77,9 @@ const InternalPromptInput = React.forwardRef( select() { textareaRef.current?.select(); }, + setSelectionRange(...args: Parameters) { + textareaRef.current?.setSelectionRange(...args); + }, }), [textareaRef] );