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);
 ...