guesstimate/client/src/components/EditableText/EditableText.tsx

61 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, {
FunctionComponent, Fragment,
ReactNode, ChangeEvent,
useState, useEffect
} from "react";
import * as style from "./style.module.css";
export interface EditableTextProps {
value: string
class?: string
editIconClass?: string
onChange?: (value: string) => void
render?: (value: string) => ReactNode
}
const EditableText: FunctionComponent<EditableTextProps> = ({ onChange, value, render, ...props }) => {
const [ internalValue, setInternalValue ] = useState(value);
const [ editMode, setEditMode ] = useState(false);
useEffect(() => {
setInternalValue(value);
}, [value])
const onEditIconClick = () => {
setEditMode(true);
};
const onValidateButtonClick = () => {
setEditMode(false);
if (internalValue === value) return;
if (onChange) onChange(internalValue);
}
const onValueChange = (evt: ChangeEvent) => {
const currentTarget = evt.currentTarget as HTMLInputElement;
setInternalValue(currentTarget.value);
};
return (
<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>
}
</div>
);
};
export default EditableText;