From 64ea2ee86264a20f1d0e34968831945fea8ed36b Mon Sep 17 00:00:00 2001 From: Matthew Date: Wed, 27 Nov 2024 08:47:44 -0600 Subject: [PATCH] remove findDOMNode from text-input (#1919) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary: `findDOMNode` is deprecated and React whines about it constantly when running tests, so I'm trying to chip away at removing uses of it. Author: handeyeco Reviewers: handeyeco, jeremywiebe Required Reviewers: Approved By: jeremywiebe Checks: ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Lint, Typecheck, Format, and Test (ubuntu-latest, 20.x), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ Cypress (ubuntu-latest, 20.x), ✅ Check builds for changes in size (ubuntu-latest, 20.x), ✅ Publish Storybook to Chromatic (ubuntu-latest, 20.x), ✅ gerald Pull Request URL: https://github.com/Khan/perseus/pull/1919 --- .changeset/giant-tables-impress.md | 5 +++ .../perseus/src/components/text-input.tsx | 43 ++++++++++--------- 2 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 .changeset/giant-tables-impress.md diff --git a/.changeset/giant-tables-impress.md b/.changeset/giant-tables-impress.md new file mode 100644 index 0000000000..32f5de4204 --- /dev/null +++ b/.changeset/giant-tables-impress.md @@ -0,0 +1,5 @@ +--- +"@khanacademy/perseus": patch +--- + +Remove usage of findDOMNode in text-input component diff --git a/packages/perseus/src/components/text-input.tsx b/packages/perseus/src/components/text-input.tsx index abcb259260..83ad468395 100644 --- a/packages/perseus/src/components/text-input.tsx +++ b/packages/perseus/src/components/text-input.tsx @@ -1,7 +1,7 @@ /* eslint-disable @khanacademy/ts-no-error-suppressions */ +import {Errors, PerseusError} from "@khanacademy/perseus-core"; import {TextField} from "@khanacademy/wonder-blocks-form"; import * as React from "react"; -import ReactDOM from "react-dom"; import type {StyleType} from "@khanacademy/wonder-blocks-core"; @@ -31,6 +31,7 @@ function uniqueIdForInput(prefix = "input-") { } class TextInput extends React.Component { + inputRef = React.createRef(); static defaultProps: DefaultProps = { value: "", disabled: false, @@ -47,45 +48,46 @@ class TextInput extends React.Component { } } + _getInput: () => HTMLInputElement = () => { + if (!this.inputRef.current) { + throw new PerseusError( + "Input ref accessed before set", + Errors.Internal, + ); + } + + return this.inputRef.current; + }; + focus: () => void = () => { - // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'focus' does not exist on type 'Element | Text'. - ReactDOM.findDOMNode(this).focus(); + this._getInput().focus(); }; blur: () => void = () => { - // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'blur' does not exist on type 'Element | Text'. - ReactDOM.findDOMNode(this).blur(); + this._getInput().blur(); }; getValue: () => string | null | undefined = () => { - // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'Element | Text'. - return ReactDOM.findDOMNode(this)?.value; + return this.inputRef.current?.value; }; getStringValue: () => string | null | undefined = () => { - // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'Element | Text'. - return ReactDOM.findDOMNode(this)?.value.toString(); + return this.inputRef.current?.value.toString(); }; setSelectionRange: (arg1: number, arg2: number) => void = ( selectionStart, selectionEnd, ) => { - // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'setSelectionRange' does not exist on type 'Element | Text'. - ReactDOM.findDOMNode(this).setSelectionRange( - selectionStart, - selectionEnd, - ); + this._getInput().setSelectionRange(selectionStart, selectionEnd); }; - getSelectionStart: () => number = () => { - // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'selectionStart' does not exist on type 'Element | Text'. - return ReactDOM.findDOMNode(this).selectionStart; + getSelectionStart: () => number | null = () => { + return this._getInput().selectionStart; }; - getSelectionEnd: () => number = () => { - // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'selectionEnd' does not exist on type 'Element | Text'. - return ReactDOM.findDOMNode(this).selectionEnd; + getSelectionEnd: () => number | null = () => { + return this._getInput().selectionEnd; }; render(): React.ReactNode { @@ -104,6 +106,7 @@ class TextInput extends React.Component { return (