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:...