Tooltip: close field tooltip when ESC is pressed (#12553)

* Close field tooltip when ESC is pressed

* Use `Key.ESCAPE`
This commit is contained in:
Florian Duros 2024-05-28 14:55:47 +02:00 committed by GitHub
parent e8bb2419c9
commit 17ab522942
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 34 additions and 2 deletions

View file

@ -14,12 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React, { InputHTMLAttributes, SelectHTMLAttributes, TextareaHTMLAttributes, RefObject, createRef } from "react"; import React, {
InputHTMLAttributes,
SelectHTMLAttributes,
TextareaHTMLAttributes,
RefObject,
createRef,
KeyboardEvent,
} from "react";
import classNames from "classnames"; import classNames from "classnames";
import { debounce } from "lodash"; import { debounce } from "lodash";
import { IFieldState, IValidationResult } from "./Validation"; import { IFieldState, IValidationResult } from "./Validation";
import Tooltip from "./Tooltip"; import Tooltip from "./Tooltip";
import { Key } from "../../../Keyboard";
// Invoke validation from user input (when typing, etc.) at most once every N ms. // Invoke validation from user input (when typing, etc.) at most once every N ms.
const VALIDATION_THROTTLE_MS = 200; const VALIDATION_THROTTLE_MS = 200;
@ -232,6 +240,18 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
return this.props.inputRef ?? this._inputRef; return this.props.inputRef ?? this._inputRef;
} }
private onKeyDown = (evt: KeyboardEvent<HTMLDivElement>): void => {
// If the tooltip is displayed to show a feedback and Escape is pressed
// The tooltip is hided
if (this.state.feedbackVisible && evt.key === Key.ESCAPE) {
evt.preventDefault();
evt.stopPropagation();
this.setState({
feedbackVisible: false,
});
}
};
public render(): React.ReactNode { public render(): React.ReactNode {
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */ /* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
const { const {
@ -318,7 +338,7 @@ export default class Field extends React.PureComponent<PropShapes, IState> {
}); });
return ( return (
<div className={fieldClasses}> <div className={fieldClasses} onKeyDown={this.onKeyDown}>
{prefixContainer} {prefixContainer}
{fieldInput} {fieldInput}
<label htmlFor={this.id}>{this.props.label}</label> <label htmlFor={this.id}>{this.props.label}</label>

View file

@ -69,6 +69,10 @@ describe("Field", () => {
// Expect 'alert' role // Expect 'alert' role
expect(screen.queryByRole("alert")).toBeInTheDocument(); expect(screen.queryByRole("alert")).toBeInTheDocument();
// Close the feedback is Escape is pressed
fireEvent.keyDown(screen.getByRole("textbox"), { key: "Escape" });
expect(screen.queryByRole("alert")).toBeNull();
}); });
it("Should mark the feedback as status if valid", async () => { it("Should mark the feedback as status if valid", async () => {
@ -87,6 +91,10 @@ describe("Field", () => {
// Expect 'status' role // Expect 'status' role
expect(screen.queryByRole("status")).toBeInTheDocument(); expect(screen.queryByRole("status")).toBeInTheDocument();
// Close the feedback is Escape is pressed
fireEvent.keyDown(screen.getByRole("textbox"), { key: "Escape" });
expect(screen.queryByRole("status")).toBeNull();
}); });
it("Should mark the feedback as tooltip if custom tooltip set", async () => { it("Should mark the feedback as tooltip if custom tooltip set", async () => {
@ -106,6 +114,10 @@ describe("Field", () => {
// Expect 'tooltip' role // Expect 'tooltip' role
expect(screen.queryByRole("tooltip")).toBeInTheDocument(); expect(screen.queryByRole("tooltip")).toBeInTheDocument();
// Close the feedback is Escape is pressed
fireEvent.keyDown(screen.getByRole("textbox"), { key: "Escape" });
expect(screen.queryByRole("tooltip")).toBeNull();
}); });
}); });
}); });