added a keydown listener to focus property pane title on pressing f2
This commit is contained in:
parent
5d6aec7ede
commit
842828b187
34
app/client/src/components/ads/EditableText.test.tsx
Normal file
34
app/client/src/components/ads/EditableText.test.tsx
Normal 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");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -16,7 +16,8 @@ export type EditableTextProps = CommonComponentProps & {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
editInteractionKind: EditInteractionKind;
|
editInteractionKind: EditInteractionKind;
|
||||||
savingState: SavingState;
|
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;
|
onTextChanged?: (value: string) => void;
|
||||||
valueTransform?: (value: string) => string;
|
valueTransform?: (value: string) => string;
|
||||||
isEditingDefault?: boolean;
|
isEditingDefault?: boolean;
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ export type EditableTextSubComponentProps = CommonComponentProps & {
|
||||||
defaultSavingState: SavingState;
|
defaultSavingState: SavingState;
|
||||||
savingState: SavingState;
|
savingState: SavingState;
|
||||||
setSavingState: typeof noop;
|
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;
|
onTextChanged?: (value: string) => void;
|
||||||
valueTransform?: (value: string) => string;
|
valueTransform?: (value: string) => string;
|
||||||
isEditingDefault?: boolean;
|
isEditingDefault?: boolean;
|
||||||
|
|
@ -159,6 +160,7 @@ export function EditableTextSubComponent(props: EditableTextSubComponentProps) {
|
||||||
isError,
|
isError,
|
||||||
isInvalid,
|
isInvalid,
|
||||||
onBlur,
|
onBlur,
|
||||||
|
onBlurEverytime,
|
||||||
onTextChanged,
|
onTextChanged,
|
||||||
savingState,
|
savingState,
|
||||||
setIsEditing,
|
setIsEditing,
|
||||||
|
|
@ -204,6 +206,7 @@ export function EditableTextSubComponent(props: EditableTextSubComponentProps) {
|
||||||
const onConfirm = useCallback(
|
const onConfirm = useCallback(
|
||||||
(_value: string) => {
|
(_value: string) => {
|
||||||
const finalVal: string = _value.trim();
|
const finalVal: string = _value.trim();
|
||||||
|
onBlurEverytime && onBlurEverytime(finalVal);
|
||||||
if (savingState === SavingState.ERROR || isInvalid || finalVal === "") {
|
if (savingState === SavingState.ERROR || isInvalid || finalVal === "") {
|
||||||
setValue(lastValidValue);
|
setValue(lastValidValue);
|
||||||
onBlur && onBlur(lastValidValue);
|
onBlur && onBlur(lastValidValue);
|
||||||
|
|
|
||||||
30
app/client/src/pages/Editor/PropertyPaneTitle.test.tsx
Normal file
30
app/client/src/pages/Editor/PropertyPaneTitle.test.tsx
Normal 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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -95,6 +95,27 @@ const PropertyPaneTitle = memo(function PropertyPaneTitle(
|
||||||
setName(props.title);
|
setName(props.title);
|
||||||
}, [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 ? (
|
return props.widgetId || props.isPanelTitle ? (
|
||||||
<div className="flex items-center w-full px-3 space-x-1 z-3">
|
<div className="flex items-center w-full px-3 space-x-1 z-3">
|
||||||
{/* BACK BUTTON */}
|
{/* BACK BUTTON */}
|
||||||
|
|
@ -114,8 +135,9 @@ const PropertyPaneTitle = memo(function PropertyPaneTitle(
|
||||||
editInteractionKind={EditInteractionKind.SINGLE}
|
editInteractionKind={EditInteractionKind.SINGLE}
|
||||||
fill
|
fill
|
||||||
hideEditIcon
|
hideEditIcon
|
||||||
isEditingDefault={!props.isPanelTitle ? isNew : undefined}
|
isEditingDefault={isEditingDefault}
|
||||||
onBlur={!props.isPanelTitle ? updateTitle : undefined}
|
onBlur={!props.isPanelTitle ? updateTitle : undefined}
|
||||||
|
onBlurEverytime={handleOnBlurEverytime}
|
||||||
onTextChanged={!props.isPanelTitle ? undefined : updateNewTitle}
|
onTextChanged={!props.isPanelTitle ? undefined : updateNewTitle}
|
||||||
placeholder={props.title}
|
placeholder={props.title}
|
||||||
savingState={updating ? SavingState.STARTED : SavingState.NOT_STARTED}
|
savingState={updating ? SavingState.STARTED : SavingState.NOT_STARTED}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user