- Wrap the methods passed to editableText component with useCallback
- Use destructing for props
This commit is contained in:
parent
7df8581a5f
commit
bbecba125e
|
|
@ -92,10 +92,25 @@ const TextContainer = styled.div<{ isValid: boolean; minimal: boolean }>`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function EditableText(props: EditableTextProps) {
|
export function EditableText(props: EditableTextProps) {
|
||||||
const [isEditing, setIsEditing] = useState(!!props.isEditingDefault);
|
const {
|
||||||
const [value, setStateValue] = useState(props.defaultValue);
|
beforeUnmount,
|
||||||
|
className,
|
||||||
|
defaultValue,
|
||||||
|
editInteractionKind,
|
||||||
|
forceDefault,
|
||||||
|
hideEditIcon,
|
||||||
|
isEditingDefault,
|
||||||
|
isInvalid,
|
||||||
|
minimal,
|
||||||
|
onBlur,
|
||||||
|
onTextChanged,
|
||||||
|
placeholder,
|
||||||
|
updating,
|
||||||
|
valueTransform,
|
||||||
|
} = props;
|
||||||
|
const [isEditing, setIsEditing] = useState(!!isEditingDefault);
|
||||||
|
const [value, setStateValue] = useState(defaultValue);
|
||||||
const inputValRef = useRef("");
|
const inputValRef = useRef("");
|
||||||
const { beforeUnmount } = props;
|
|
||||||
|
|
||||||
const setValue = useCallback((value) => {
|
const setValue = useCallback((value) => {
|
||||||
inputValRef.current = value;
|
inputValRef.current = value;
|
||||||
|
|
@ -103,16 +118,16 @@ export function EditableText(props: EditableTextProps) {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setValue(props.defaultValue);
|
setValue(defaultValue);
|
||||||
}, [props.defaultValue]);
|
}, [defaultValue]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsEditing(!!props.isEditingDefault);
|
setIsEditing(!!isEditingDefault);
|
||||||
}, [props.defaultValue, props.isEditingDefault]);
|
}, [defaultValue, isEditingDefault]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.forceDefault === true) setValue(props.defaultValue);
|
if (forceDefault === true) setValue(defaultValue);
|
||||||
}, [props.forceDefault, props.defaultValue]);
|
}, [forceDefault, defaultValue]);
|
||||||
|
|
||||||
// at times onTextChange is not fired
|
// at times onTextChange is not fired
|
||||||
// for example when the modal is closed on clicking the overlay
|
// for example when the modal is closed on clicking the overlay
|
||||||
|
|
@ -128,58 +143,63 @@ export function EditableText(props: EditableTextProps) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
};
|
};
|
||||||
const onChange = (_value: string) => {
|
const onChange = useCallback(
|
||||||
props.onBlur && props.onBlur();
|
(_value: string) => {
|
||||||
const isInvalid = props.isInvalid ? props.isInvalid(_value) : false;
|
onBlur && onBlur();
|
||||||
if (!isInvalid) {
|
const _isInvalid = isInvalid ? isInvalid(_value) : false;
|
||||||
props.onTextChanged(_value);
|
if (!_isInvalid) {
|
||||||
setIsEditing(false);
|
onTextChanged(_value);
|
||||||
} else {
|
setIsEditing(false);
|
||||||
Toaster.show({
|
} else {
|
||||||
text: "Invalid name",
|
Toaster.show({
|
||||||
variant: Variant.danger,
|
text: "Invalid name",
|
||||||
});
|
variant: Variant.danger,
|
||||||
}
|
});
|
||||||
};
|
}
|
||||||
|
},
|
||||||
|
[isInvalid],
|
||||||
|
);
|
||||||
|
|
||||||
const onInputchange = (_value: string) => {
|
const onInputchange = useCallback(
|
||||||
let finalVal: string = _value;
|
(_value: string) => {
|
||||||
if (props.valueTransform) {
|
let finalVal: string = _value;
|
||||||
finalVal = props.valueTransform(_value);
|
if (valueTransform) {
|
||||||
}
|
finalVal = valueTransform(_value);
|
||||||
setValue(finalVal);
|
}
|
||||||
};
|
setValue(finalVal);
|
||||||
|
},
|
||||||
|
[valueTransform],
|
||||||
|
);
|
||||||
|
|
||||||
const errorMessage = props.isInvalid && props.isInvalid(value);
|
const errorMessage = isInvalid && isInvalid(value);
|
||||||
const error = errorMessage ? errorMessage : undefined;
|
const error = errorMessage ? errorMessage : undefined;
|
||||||
return (
|
return (
|
||||||
<EditableTextWrapper
|
<EditableTextWrapper
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
minimal={!!props.minimal}
|
minimal={!!minimal}
|
||||||
onClick={
|
onClick={
|
||||||
props.editInteractionKind === EditInteractionKind.SINGLE ? edit : _.noop
|
editInteractionKind === EditInteractionKind.SINGLE ? edit : _.noop
|
||||||
}
|
}
|
||||||
onDoubleClick={
|
onDoubleClick={
|
||||||
props.editInteractionKind === EditInteractionKind.DOUBLE ? edit : _.noop
|
editInteractionKind === EditInteractionKind.DOUBLE ? edit : _.noop
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ErrorTooltip isOpen={!!error} message={errorMessage as string}>
|
<ErrorTooltip isOpen={!!error} message={errorMessage as string}>
|
||||||
<TextContainer isValid={!error} minimal={!!props.minimal}>
|
<TextContainer isValid={!error} minimal={!!minimal}>
|
||||||
<BlueprintEditableText
|
<BlueprintEditableText
|
||||||
className={props.className}
|
className={className}
|
||||||
disabled={!isEditing}
|
disabled={!isEditing}
|
||||||
isEditing={isEditing}
|
isEditing={isEditing}
|
||||||
onCancel={props.onBlur}
|
onCancel={onBlur}
|
||||||
onChange={onInputchange}
|
onChange={onInputchange}
|
||||||
onConfirm={onChange}
|
onConfirm={onChange}
|
||||||
placeholder={props.placeholder}
|
placeholder={placeholder}
|
||||||
selectAllOnFocus
|
selectAllOnFocus
|
||||||
value={value}
|
value={value}
|
||||||
/>
|
/>
|
||||||
{!props.minimal &&
|
{!minimal && !hideEditIcon && !updating && !isEditing && (
|
||||||
!props.hideEditIcon &&
|
<EditPen alt="Edit pen" src={Edit} />
|
||||||
!props.updating &&
|
)}
|
||||||
!isEditing && <EditPen alt="Edit pen" src={Edit} />}
|
|
||||||
</TextContainer>
|
</TextContainer>
|
||||||
</ErrorTooltip>
|
</ErrorTooltip>
|
||||||
</EditableTextWrapper>
|
</EditableTextWrapper>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user