guesstimate/client/src/components/editable-text/index.tsx

64 lines
1.9 KiB
TypeScript
Raw Normal View History

2020-07-09 13:00:42 +02:00
import React, {
FunctionComponent, Fragment,
ReactNode, ChangeEvent,
useState, useEffect
} from "react";
2020-04-22 22:07:52 +02:00
import * as style from "./style.module.css";
2020-04-21 09:24:39 +02:00
export interface EditableTextProps {
value: string
class?: string
editIconClass?: string
onChange?: (value: string) => void
2020-07-09 13:00:42 +02:00
render?: (value: string) => ReactNode
2020-04-21 09:24:39 +02:00
}
2020-07-09 13:00:42 +02:00
const EditableText: FunctionComponent<EditableTextProps> = ({ onChange, value, render, ...props }) => {
2020-04-21 09:24:39 +02:00
const [ internalValue, setInternalValue ] = useState(value);
const [ editMode, setEditMode ] = useState(false);
useEffect(() => {
if (internalValue === value) return;
if (onChange) onChange(internalValue);
2020-04-21 09:24:39 +02:00
}, [internalValue]);
useEffect(() => {
setInternalValue(value);
}, [value])
2020-04-21 09:24:39 +02:00
const onEditIconClick = () => {
setEditMode(true);
};
const onValidateButtonClick = () => {
setEditMode(false);
}
2020-07-09 13:00:42 +02:00
const onValueChange = (evt: ChangeEvent) => {
2020-04-21 09:24:39 +02:00
const currentTarget = evt.currentTarget as HTMLInputElement;
setInternalValue(currentTarget.value);
};
return (
2020-07-09 13:00:42 +02:00
<div className={`${style.editableText} ${props.class ? props.class : ''}`}>
{
editMode ?
<div className="field has-addons">
<div className="control">
<input className="input is-expanded" type="text" value={internalValue} onChange={onValueChange} />
</div>
<div className="control">
<a className="button" onClick={onValidateButtonClick}></a>
</div>
</div> :
<Fragment>
{ render ? render(internalValue) : <span>{internalValue}</span> }
<i className={`${style.editIcon} icon ${props.editIconClass ? props.editIconClass : ''}`} onClick={onEditIconClick}>🖋</i>
</Fragment>
}
2020-04-21 09:24:39 +02:00
</div>
);
};
export default EditableText;