PromucFlow_constructor/app/client/src/components/editorComponents/EditableText.tsx

141 lines
3.6 KiB
TypeScript
Raw Normal View History

2020-01-27 08:24:58 +00:00
import React, { useState, useEffect } from "react";
2020-02-21 12:16:49 +00:00
import {
EditableText as BlueprintEditableText,
Classes,
} from "@blueprintjs/core";
2020-01-27 08:24:58 +00:00
import styled from "styled-components";
2020-06-18 07:46:53 +00:00
import _ from "lodash";
import Edit from "assets/images/EditPen.svg";
import ErrorTooltip from "./ErrorTooltip";
export enum EditInteractionKind {
SINGLE,
DOUBLE,
}
2020-01-27 08:24:58 +00:00
type EditableTextProps = {
type: "text" | "password" | "email" | "phone" | "date";
defaultValue: string;
onTextChanged: (value: string) => void;
placeholder: string;
2020-03-30 14:21:21 +00:00
className?: string;
2020-06-18 07:46:53 +00:00
valueTransform?: (value: string) => string;
isEditingDefault?: boolean;
forceDefault?: boolean;
updating?: boolean;
isInvalid?: (value: string) => string | boolean;
editInteractionKind: EditInteractionKind;
hideEditIcon?: boolean;
2020-01-27 08:24:58 +00:00
};
2020-06-18 07:46:53 +00:00
const EditPen = styled.img`
width: 14px;
: hover {
cursor: pointer;
}
`;
2020-01-27 08:24:58 +00:00
const EditableTextWrapper = styled.div<{ isEditing: boolean }>`
&& {
2020-06-18 07:46:53 +00:00
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
2020-02-21 12:16:49 +00:00
& .${Classes.EDITABLE_TEXT} {
2020-01-27 08:24:58 +00:00
border: ${props => (props.isEditing ? "1px solid #ccc" : "none")};
cursor: pointer;
2020-06-18 07:46:53 +00:00
padding: 5px 5px;
2020-02-21 12:16:49 +00:00
text-transform: none;
2020-06-18 07:46:53 +00:00
flex: 1 0 100%;
max-width: 100%;
display: flex;
2020-01-27 08:24:58 +00:00
&:before,
&:after {
display: none;
}
}
2020-02-21 12:16:49 +00:00
& div.${Classes.EDITABLE_TEXT_INPUT} {
text-transform: none;
2020-06-18 07:46:53 +00:00
width: 100%;
2020-02-21 12:16:49 +00:00
}
2020-01-27 08:24:58 +00:00
}
`;
2020-06-18 07:46:53 +00:00
const TextContainer = styled.div<{ isValid: boolean }>`
display: flex;
&&&& .bp3-editable-text {
border-radius: 3px;
border-color: ${props => (props.isValid ? "hsl(0,0%,80%)" : "red")};
}
`;
2020-01-27 08:24:58 +00:00
export const EditableText = (props: EditableTextProps) => {
2020-06-18 07:46:53 +00:00
const [isEditing, setIsEditing] = useState(!!props.isEditingDefault);
const [value, setValue] = useState(props.defaultValue);
2020-01-27 08:24:58 +00:00
useEffect(() => {
2020-06-18 07:46:53 +00:00
setValue(props.defaultValue);
}, [props.defaultValue]);
useEffect(() => {
if (props.forceDefault === true) setValue(props.defaultValue);
}, [props.forceDefault]);
2020-01-27 08:24:58 +00:00
const edit = (e: any) => {
setIsEditing(true);
e.preventDefault();
e.stopPropagation();
};
2020-06-18 07:46:53 +00:00
const onChange = (_value: string) => {
const isInvalid = props.isInvalid ? props.isInvalid(_value) : false;
if (!isInvalid) {
props.onTextChanged(_value);
} else {
setValue(props.defaultValue);
}
2020-01-27 08:24:58 +00:00
setIsEditing(false);
};
2020-06-18 07:46:53 +00:00
const onInputchange = (_value: string) => {
let finalVal: string = _value;
if (props.valueTransform) {
finalVal = props.valueTransform(_value);
}
setValue(finalVal);
};
const errorMessage = props.isInvalid && props.isInvalid(value);
const error = errorMessage ? errorMessage : undefined;
2020-01-27 08:24:58 +00:00
return (
2020-06-18 07:46:53 +00:00
<EditableTextWrapper
isEditing={isEditing}
onDoubleClick={
props.editInteractionKind === EditInteractionKind.DOUBLE ? edit : _.noop
}
onClick={
props.editInteractionKind === EditInteractionKind.SINGLE ? edit : _.noop
}
>
<ErrorTooltip isOpen={!!error} message={errorMessage as string}>
<TextContainer isValid={!error}>
<BlueprintEditableText
disabled={!isEditing}
isEditing={isEditing}
onChange={onInputchange}
onConfirm={onChange}
selectAllOnFocus
value={value}
placeholder={props.placeholder}
className={props.className}
/>
{!props.hideEditIcon && !props.updating && !isEditing && (
<EditPen src={Edit} alt="Edit pen" />
)}
</TextContainer>
</ErrorTooltip>
2020-01-27 08:24:58 +00:00
</EditableTextWrapper>
);
};
export default EditableText;