HandleTable

Writable table

by evgkch

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;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}

React

const createStateCatcher = (target = null) => () => ({
  listen: (t) => target = t,
  unlisten: () => target = null,
  get: (prop) => !!target ? !!prop ? target.state[prop] : target.state : null,
});

const data = {
  head: ['head_1', 'head_2', 'head_3', 'head_4'],
  body: Array.from({ length: 5 }, (v, k) => [
    {
      type: 'text',
      writable: true,
      value: `value_1.${k}`,
      stateCatcher: createStateCatcher(),
    },
    {
      type: 'text',
      writable: true,
      value: `value_2.${k}`,
      stateCatcher: createStateCatcher(),
    },
    {
      type: 'text',
      writable: true,
      value: `value_3.${k}`,
      stateCatcher: createStateCatcher(),
    },
    {
      type: 'text',
      writable: true,
      value: `value_4.${k}`,
      stateCatcher: createStateCatcher(),
    },
  ]),
};

setTimeout(() => {
  data.body.forEach(el => {
    if (!!el[0].stateCatcher)
      console.log(el[0].stateCatcher().get('value'));
  })
}, 4000)


class WritableText extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      writeMode: false,
      value: this.props.value || '',
    };   
    window.addEventListener('click', this.onClick);
    window.addEventListener('keypress', this.onKeyPress);
    if (!!this.props.stateCatcher)
      this.props.stateCatcher().listen(this);
  }

  componentWillUnmount() {
    window.removeEventListener('click', this.onClick);
    window.removeEventListener('keypress', this.onClick);
    if (!!this.props.stateCatcher)
      this.props.stateCatcher().unlisten();
  }
  
  setRefToInput = input => {
  	this.input = input;
  }
  
  setRefToText = text => {
  	this.text = text;
  }

  onKeyPress = e => {
    const { writeMode } = this.state;
    switch (e.keyCode)
    {
    case 13: if (writeMode) this.disableWrite(); break;
    default: break;
    }
  }

  onClick = e => {
  	console.log('!')
    const { writeMode } = this.state;
    switch (e.target)
    {
    case this.text:...