added a keydown listener to focus property pane title on pressing f2

This commit is contained in:
Ankur Singhal 2022-01-27 16:40:57 +05:30
parent 5d6aec7ede
commit 842828b187
5 changed files with 93 additions and 3 deletions

View File

@ -0,0 +1,34 @@
import React from "react";
import "@testing-library/jest-dom";
import { render } from "@testing-library/react";
import EditableText from "./EditableText";
import userEvent from "@testing-library/user-event";
import { EditInteractionKind, SavingState } from "./EditableTextSubComponent";
import { ThemeProvider } from "constants/DefaultTheme";
import { lightTheme } from "selectors/themeSelectors";
describe("<EditableText />", () => {
it("should call onBlurEverytime on each and every blur", async () => {
const handleBlur = jest.fn();
const getTestComponent = () => (
<ThemeProvider theme={lightTheme}>
<EditableText
defaultValue="Test"
editInteractionKind={EditInteractionKind.SINGLE}
onBlurEverytime={handleBlur}
savingState={SavingState.NOT_STARTED}
/>
</ThemeProvider>
);
const component = getTestComponent();
const renderResult = render(component);
const EditableTextElement = renderResult.container.firstElementChild;
if (EditableTextElement) {
userEvent.click(EditableTextElement);
userEvent.tab();
expect(handleBlur).toHaveBeenCalled();
} else {
throw new Error("Failed");
}
});
});

View File

@ -16,7 +16,8 @@ export type EditableTextProps = CommonComponentProps & {
placeholder?: string;
editInteractionKind: EditInteractionKind;
savingState: SavingState;
onBlur?: (value: string) => void;
onBlur?: (value: string) => void; // This `Blur` will be called only when there is a change in the value after we unfocus from the input field
onBlurEverytime?: (value: string) => void; // This `Blur` will be called everytime we unfocus from the input field
onTextChanged?: (value: string) => void;
valueTransform?: (value: string) => string;
isEditingDefault?: boolean;

View File

@ -38,7 +38,8 @@ export type EditableTextSubComponentProps = CommonComponentProps & {
defaultSavingState: SavingState;
savingState: SavingState;
setSavingState: typeof noop;
onBlur?: (value: string) => void;
onBlur?: (value: string) => void; // This `Blur` will be called only when there is a change in the value after we unfocus from the input field
onBlurEverytime?: (value: string) => void; // This `Blur` will be called everytime we unfocus from the input field
onTextChanged?: (value: string) => void;
valueTransform?: (value: string) => string;
isEditingDefault?: boolean;
@ -159,6 +160,7 @@ export function EditableTextSubComponent(props: EditableTextSubComponentProps) {
isError,
isInvalid,
onBlur,
onBlurEverytime,
onTextChanged,
savingState,
setIsEditing,
@ -204,6 +206,7 @@ export function EditableTextSubComponent(props: EditableTextSubComponentProps) {
const onConfirm = useCallback(
(_value: string) => {
const finalVal: string = _value.trim();
onBlurEverytime && onBlurEverytime(finalVal);
if (savingState === SavingState.ERROR || isInvalid || finalVal === "") {
setValue(lastValidValue);
onBlur && onBlur(lastValidValue);

View File

@ -0,0 +1,30 @@
import React from "react";
import "@testing-library/jest-dom";
import { render } from "@testing-library/react";
import PropertyPaneTitle from "./PropertyPaneTitle";
import userEvent from "@testing-library/user-event";
import { ThemeProvider } from "constants/DefaultTheme";
import { lightTheme } from "selectors/themeSelectors";
import { Provider } from "react-redux";
import store from "../../store";
describe("<PropertyPaneTitle />", () => {
it("should focus when f2 is pressed", async () => {
const getTestComponent = () => (
<Provider store={store}>
<ThemeProvider theme={lightTheme}>
<PropertyPaneTitle
actions={[]}
isPanelTitle
// title="test"
widgetId="1"
/>
</ThemeProvider>
</Provider>
);
const component = getTestComponent();
const renderResult = render(component);
await userEvent.keyboard("{F2}");
expect(renderResult.container.querySelector("input")).toBeVisible();
});
});

View File

@ -95,6 +95,27 @@ const PropertyPaneTitle = memo(function PropertyPaneTitle(
setName(props.title);
}, [props.title]);
// Focus title on F2
const [isEditingDefault, setIsEditingDefault] = useState(
!props.isPanelTitle ? isNew : undefined,
);
function handleKeyDown(e: KeyboardEvent) {
if (e.key === "F2") {
setIsEditingDefault(true);
}
}
function handleOnBlurEverytime() {
setIsEditingDefault(false);
}
useEffect(() => {
document.addEventListener("keydown", handleKeyDown);
return () => document.removeEventListener("keydown", handleKeyDown);
});
return props.widgetId || props.isPanelTitle ? (
<div className="flex items-center w-full px-3 space-x-1 z-3">
{/* BACK BUTTON */}
@ -114,8 +135,9 @@ const PropertyPaneTitle = memo(function PropertyPaneTitle(
editInteractionKind={EditInteractionKind.SINGLE}
fill
hideEditIcon
isEditingDefault={!props.isPanelTitle ? isNew : undefined}
isEditingDefault={isEditingDefault}
onBlur={!props.isPanelTitle ? updateTitle : undefined}
onBlurEverytime={handleOnBlurEverytime}
onTextChanged={!props.isPanelTitle ? undefined : updateNewTitle}
placeholder={props.title}
savingState={updating ? SavingState.STARTED : SavingState.NOT_STARTED}