React
by Abdul Ahmad
HTML
<div id="app"></div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
button {
margin-left: 20px;
}
.title {
font-weight: bold;
margin-bottom: 5px;
}
.editable-field {
margin-top: 20px;
}
.update-indicator {
display: inline-block;
vertical-align: middle;
padding: 4px 8px 5px;
border-radius: 5px;
background: #52ce50;
font-size: 10px;
color: white;
margin-left: 5px;
}
React
function App() {
const [name, setName] = React.useState('abdul');
return (
<div>
<h4>
fields
</h4>
<EditableField
title='Name'
text={name}
Form={(props) => <EditNameForm value={name} onSubmit={setName} {...props} />}
/>
</div>
);
}
function EditUpdateIndicator({ children, isUpdated, onComplete }) {
const [updated, setUpdated] = React.useState(false);
const timeoutId = React.useRef(undefined);
if (isUpdated && !updated) {
setUpdated(true);
if (timeoutId.current) {
clearTimeout(timeoutId.current);
timeoutId.current = undefined;
}
timeoutId.current = setTimeout(() => {
setUpdated(false);
onComplete();
}, 1000);
}
if (!updated) return children;
return (
<React.Fragment>
{ children }
<div className='update-indicator'>
updated
</div>
</React.Fragment>
);
}
function EditableField({ title, text, Form }) {
const [editing, setEditing] = React.useState(false);
const [editSuccess, setEditSuccess] = React.useState(false);
function onEdit() {
setEditing(true);
}
return (
<div className='editable-field'>
<div className='title'>
{ title }
</div>
{
editing && <Form onSubmitSuccess={() => {
setEditing(false);
setEditSuccess(true);
}} />
}
{
!editing && (
<React.Fragment>
<EditUpdateIndicator
isUpdated={editSuccess}
onComplete={() => setEditSuccess(false)}
>
<span>
{ text }
</span>
</EditUpdateIndicator>
<button onClick={onEdit}>
edit
</button>
</React.Fragment>
)
}
</div>
);
}
function EditNameForm({ value, onSubmit, onSubmitSuccess }) {
const [name, setName] = React.useState(value);
const inputRef = React.useRef(null);
...