feat: remove isFocus from meta state in InputWidgetV2 (#36843)
## Description **Problem** A redundant evaluation cycle is run every time a user focuses on an InputWidget component and the isFocused meta state is updated **Root Cause** `isFocus` property of InputWidgetV2 is a meta property and updated through `this.updateWidgetMetaProperty`, thereby changes to these property triggers an evaluation cycle run **Solution** Implement the `isFocus` property as a local state of the InputWidgetV2 component Fixes #36446 ## Automation /ok-to-test tags="@tag.Widget, @tag.Input" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/11362334893> > Commit: 80e9089681456b7b3547cc4781abf719c561d27d > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=11362334893&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Widget, @tag.Input` > Spec: > <hr>Wed, 16 Oct 2024 10:22:00 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Enhanced focus management for the InputWidget, allowing for improved internal state handling. - Multi-line text input now supports submitting with keyboard shortcuts for a more streamlined user experience. - **Bug Fixes** - Resolved issues with widget metadata by excluding the `isFocused` property from the meta properties. - Improved internal state management for input changes, reducing reliance on external properties. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
24d989d987
commit
641e4192a6
|
|
@ -520,7 +520,6 @@ class BaseInputWidget<
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
return {
|
return {
|
||||||
text: undefined,
|
text: undefined,
|
||||||
isFocused: false,
|
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
import React from "react";
|
import type {
|
||||||
import type { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
AnvilConfig,
|
||||||
import type { InputComponentProps } from "../component";
|
AutocompletionDefinitions,
|
||||||
import InputComponent from "../component";
|
} from "WidgetProvider/constants";
|
||||||
|
import { ICON_NAMES } from "WidgetProvider/constants";
|
||||||
|
import type { DerivedPropertiesMap } from "WidgetProvider/factory";
|
||||||
|
import { LabelPosition } from "components/constants";
|
||||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||||
import type { ValidationResponse } from "constants/WidgetValidation";
|
import type { ValidationResponse } from "constants/WidgetValidation";
|
||||||
import { ValidationTypes } from "constants/WidgetValidation";
|
import { ValidationTypes } from "constants/WidgetValidation";
|
||||||
|
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||||
import {
|
import {
|
||||||
createMessage,
|
createMessage,
|
||||||
FIELD_REQUIRED_ERROR,
|
FIELD_REQUIRED_ERROR,
|
||||||
|
|
@ -13,44 +17,40 @@ import {
|
||||||
INPUT_DEFAULT_TEXT_MIN_NUM_ERROR,
|
INPUT_DEFAULT_TEXT_MIN_NUM_ERROR,
|
||||||
INPUT_TEXT_MAX_CHAR_ERROR,
|
INPUT_TEXT_MAX_CHAR_ERROR,
|
||||||
} from "ee/constants/messages";
|
} from "ee/constants/messages";
|
||||||
import type { DerivedPropertiesMap } from "WidgetProvider/factory";
|
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||||
import { ICON_NAMES } from "WidgetProvider/constants";
|
|
||||||
import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType";
|
|
||||||
import BaseInputWidget from "widgets/BaseInputWidget";
|
|
||||||
import { isNil, isNumber, merge, toString } from "lodash";
|
import { isNil, isNumber, merge, toString } from "lodash";
|
||||||
import derivedProperties from "./parsedDerivedProperties";
|
import React from "react";
|
||||||
import type { BaseInputWidgetProps } from "widgets/BaseInputWidget/widget";
|
import { DynamicHeight } from "utils/WidgetFeatures";
|
||||||
|
import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType";
|
||||||
import { mergeWidgetConfig } from "utils/helpers";
|
import { mergeWidgetConfig } from "utils/helpers";
|
||||||
|
import BaseInputWidget from "widgets/BaseInputWidget";
|
||||||
import {
|
import {
|
||||||
InputTypes,
|
InputTypes,
|
||||||
NumberInputStepButtonPosition,
|
NumberInputStepButtonPosition,
|
||||||
} from "widgets/BaseInputWidget/constants";
|
} from "widgets/BaseInputWidget/constants";
|
||||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
import { checkInputTypeTextByProps } from "widgets/BaseInputWidget/utils";
|
||||||
import { getParsedText, isInputTypeEmailOrPassword } from "./Utilities";
|
import type { BaseInputWidgetProps } from "widgets/BaseInputWidget/widget";
|
||||||
|
import type { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
||||||
import {
|
import {
|
||||||
isAutoHeightEnabledForWidget,
|
|
||||||
DefaultAutocompleteDefinitions,
|
DefaultAutocompleteDefinitions,
|
||||||
|
isAutoHeightEnabledForWidget,
|
||||||
isCompactMode,
|
isCompactMode,
|
||||||
} from "widgets/WidgetUtils";
|
} from "widgets/WidgetUtils";
|
||||||
import { checkInputTypeTextByProps } from "widgets/BaseInputWidget/utils";
|
import type { InputComponentProps } from "../component";
|
||||||
import type {
|
import InputComponent from "../component";
|
||||||
AnvilConfig,
|
import { getParsedText, isInputTypeEmailOrPassword } from "./Utilities";
|
||||||
AutocompletionDefinitions,
|
import derivedProperties from "./parsedDerivedProperties";
|
||||||
} from "WidgetProvider/constants";
|
|
||||||
import { LabelPosition } from "components/constants";
|
|
||||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
|
||||||
import { DynamicHeight } from "utils/WidgetFeatures";
|
|
||||||
|
|
||||||
import IconSVG from "../icon.svg";
|
import IconSVG from "../icon.svg";
|
||||||
import ThumbnailSVG from "../thumbnail.svg";
|
import ThumbnailSVG from "../thumbnail.svg";
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
SnipingModeProperty,
|
|
||||||
PropertyUpdates,
|
PropertyUpdates,
|
||||||
|
SnipingModeProperty,
|
||||||
} from "WidgetProvider/constants";
|
} from "WidgetProvider/constants";
|
||||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
|
||||||
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
|
import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
|
||||||
|
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||||
|
|
||||||
export function defaultValueValidation(
|
export function defaultValueValidation(
|
||||||
// TODO: Fix this the next time the file is edited
|
// TODO: Fix this the next time the file is edited
|
||||||
|
|
@ -300,6 +300,13 @@ function InputTypeUpdateHook(
|
||||||
}
|
}
|
||||||
|
|
||||||
class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
||||||
|
constructor(props: InputWidgetProps) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isFocused: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static type = "INPUT_WIDGET_V2";
|
static type = "INPUT_WIDGET_V2";
|
||||||
|
|
||||||
static getConfig() {
|
static getConfig() {
|
||||||
|
|
@ -641,7 +648,9 @@ class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
||||||
// TODO: Fix this the next time the file is edited
|
// TODO: Fix this the next time the file is edited
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
static getMetaPropertiesMap(): Record<string, any> {
|
static getMetaPropertiesMap(): Record<string, any> {
|
||||||
return merge(super.getMetaPropertiesMap(), {
|
const baseMetaProperties = BaseInputWidget.getMetaPropertiesMap();
|
||||||
|
|
||||||
|
return merge(baseMetaProperties, {
|
||||||
inputText: "",
|
inputText: "",
|
||||||
text: "",
|
text: "",
|
||||||
});
|
});
|
||||||
|
|
@ -663,8 +672,10 @@ class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFocusChange = (focusState: boolean) => {
|
handleFocusChange = (focusState: boolean) => {
|
||||||
|
this.setState({ isFocused: focusState });
|
||||||
|
|
||||||
if (focusState) {
|
if (focusState) {
|
||||||
this.props.updateWidgetMetaProperty("isFocused", focusState, {
|
this.executeAction({
|
||||||
triggerPropertyName: "onFocus",
|
triggerPropertyName: "onFocus",
|
||||||
dynamicString: this.props.onFocus,
|
dynamicString: this.props.onFocus,
|
||||||
event: {
|
event: {
|
||||||
|
|
@ -674,7 +685,7 @@ class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!focusState) {
|
if (!focusState) {
|
||||||
this.props.updateWidgetMetaProperty("isFocused", focusState, {
|
this.executeAction({
|
||||||
triggerPropertyName: "onBlur",
|
triggerPropertyName: "onBlur",
|
||||||
dynamicString: this.props.onBlur,
|
dynamicString: this.props.onBlur,
|
||||||
event: {
|
event: {
|
||||||
|
|
@ -898,7 +909,7 @@ class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
||||||
onValueChange={this.onValueChange}
|
onValueChange={this.onValueChange}
|
||||||
placeholder={this.props.placeholderText}
|
placeholder={this.props.placeholderText}
|
||||||
rtl={this.props.rtl}
|
rtl={this.props.rtl}
|
||||||
showError={!!this.props.isFocused}
|
showError={!!this.state.isFocused}
|
||||||
spellCheck={!!this.props.isSpellCheck}
|
spellCheck={!!this.props.isSpellCheck}
|
||||||
stepSize={1}
|
stepSize={1}
|
||||||
tooltip={this.props.tooltip}
|
tooltip={this.props.tooltip}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user