const F = (s,n) => RegExp(`^.{0,${n}}(\\W+|^)(\\w+)`).exec(s)[2]
class Test extends React.Component {
constructor(props) {
super(props);
const input = props.input || '';
const index = props.index || 0;
this.state = {
input,
index,
valid: /\w/.test(input),
};
}
onInput = () => {
const input = this.refs.input.value;
const index = Math.min(+this.refs.index.value, input.length);
this.setState({
input,
index,
valid: /\w/.test(input),
});
}
render() {
const {input, index, valid} = this.state;
return (
<tr>
<td>{ this.props.children }</td>
<td>
<input ref="input" type="text" onInput={this.onInput} value={input} />
<input ref="index" type="number" onInput={this.onInput} min="1" max={input.length} value={index} />
</td>
{valid && [
<td>{F(input, index)}</td>,
<td><pre>{input.slice(0, index)}|{input.slice(index)}</pre></td>,
]}
</tr>
);
}
}
class TestList extends React.Component {
constructor(props) {
super(props);
this.tid = 0;
this.state = {
tests: (props.tests || []).map(test => Object.assign({
key: this.tid++
}, test)),
};
}
addTest = () => {
this.setState({
tests: [...this.state.tests, { key: this.tid++ }],
});
}
removeTest = key => {
this.setState({
tests: this.state.tests.filter(test => test.key !== key),
});
}
render() {
return (
<div>
<table>
<thead>
<th/>
<th>Test</th>
<th>Output</th>
<th>Diagram</th>
</thead>
<tbody>
{
this.state.tests.map(test => (
<Test key={test.key} input={test.input} index={test.index}>
<button onClick={() => this.removeTest(test.key)} style={{
verticalAlign: 'middle',
}}>-</button>
</Test>
))
}
</tbody>
<tfoot>
<td/>
<td>
<button onClick={this.addTest} style={{
width: '100%',
}}>Add test case</button>
</td>
</tfoot>
</table>
</div>
);
}
}
ReactDOM.render(<TestList tests={[
{ input: 'abc def', index: 2 },
{ input: 'abc def', index: 5 },
{ input: 'abc abc', index: 2 },
{ input: 'ab cd ef', index: 4 },
{ input: 'ab cd', index: 6 },
{ input: 'ab!cd', index: 1 },
]} />, document.body);
input[type="number"] {
width: 3em;
}
table {
border-spacing: 0.5em 0;
border-collapse: separate;
margin: 0 -0.5em ;
}
td, input {
font-family: monospace;
}
th {
text-align: left;
}
tbody {
padding: 1em 0;
}
pre {
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>