|
| 1 | +/** @jsx C *//** @jsxFrag F *//** @jsxInterpolation I */ |
| 2 | + |
| 3 | +// Fully readpted from Solid-js benchmarkk |
| 4 | + |
| 5 | +import { |
| 6 | + render, |
| 7 | + signal, |
| 8 | + effect, |
| 9 | + batch, |
| 10 | + createElement as C, |
| 11 | + Fragment as F, |
| 12 | + interpolation as I |
| 13 | +} from 'udomsay'; |
| 14 | + |
| 15 | +let idCounter = 1; |
| 16 | +const adjectives = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"], |
| 17 | + colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"], |
| 18 | + nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"]; |
| 19 | + |
| 20 | +function _random (max) { return Math.round(Math.random() * 1000) % max; }; |
| 21 | + |
| 22 | +function buildData(count) { |
| 23 | + let data = new Array(count); |
| 24 | + for (let i = 0; i < count; i++) { |
| 25 | + data[i] = { |
| 26 | + id: idCounter++, |
| 27 | + label: signal(`${adjectives[_random(adjectives.length)]} ${colours[_random(colours.length)]} ${nouns[_random(nouns.length)]}`) |
| 28 | + } |
| 29 | + } |
| 30 | + return data; |
| 31 | +} |
| 32 | + |
| 33 | +const Button = ({ id, text, fn }) => ( |
| 34 | + <div class='col-sm-6 smallpad'> |
| 35 | + <button id={ id } class='btn btn-primary btn-block' type='button' onClick={ fn }>{ text }</button> |
| 36 | + </div> |
| 37 | +); |
| 38 | + |
| 39 | +const |
| 40 | + data = signal([]), |
| 41 | + selected = signal(null), |
| 42 | + run = () => { data.value = buildData(1000) }, |
| 43 | + runLots = () => { data.value = buildData(10000) }, |
| 44 | + add = () => { data.value = data.value.concat(buildData(1000)) }, |
| 45 | + update = () => batch(() => { |
| 46 | + for(let i = 0, d = data.value, len = d.length; i < len; i += 10) |
| 47 | + d[i].label.value += ' !!!'; |
| 48 | + }), |
| 49 | + swapRows = () => { |
| 50 | + const d = data.value.slice(); |
| 51 | + if (d.length > 998) { |
| 52 | + let tmp = d[1]; |
| 53 | + d[1] = d[998]; |
| 54 | + d[998] = tmp; |
| 55 | + data.value = d; |
| 56 | + } |
| 57 | + }, |
| 58 | + clear = () => { |
| 59 | + selected.value = null; |
| 60 | + data.value = []; |
| 61 | + }, |
| 62 | + remove = idx => { |
| 63 | + const {value: d} = data; |
| 64 | + data.value = [...d.slice(0, idx), ...d.slice(idx + 1)]; |
| 65 | + } |
| 66 | +; |
| 67 | + |
| 68 | +// handle danger case off the whole App |
| 69 | +// as it makes no sense to loop over and over |
| 70 | +// the same data to just switch a single class |
| 71 | +// that cannot exist in more than two rows |
| 72 | +effect(row => { |
| 73 | + const {value} = selected; |
| 74 | + if (value !== row) { |
| 75 | + if (row) |
| 76 | + row.classList.remove('danger'); |
| 77 | + if (value) |
| 78 | + value.classList.add('danger'); |
| 79 | + } |
| 80 | + return value; |
| 81 | +}); |
| 82 | + |
| 83 | +const App = () => ( |
| 84 | + <div class='container'> |
| 85 | + <div class='jumbotron'><div class='row'> |
| 86 | + <div class='col-md-6'><h1>udomsay Keyed</h1></div> |
| 87 | + <div class='col-md-6'><div class='row'> |
| 88 | + <Button id='run' text='Create 1,000 rows' fn={ run } /> |
| 89 | + <Button id='runlots' text='Create 10,000 rows' fn={ runLots } /> |
| 90 | + <Button id='add' text='Append 1,000 rows' fn={ add } /> |
| 91 | + <Button id='update' text='Update every 10th row' fn={ update } /> |
| 92 | + <Button id='clear' text='Clear' fn={ clear } /> |
| 93 | + <Button id='swaprows' text='Swap Rows' fn={ swapRows } /> |
| 94 | + </div></div> |
| 95 | + </div></div> |
| 96 | + <table class='table table-hover table-striped test-data'><tbody> |
| 97 | + {data.value.map(({id: rowId, label}, idx) => ( |
| 98 | + <tr key={rowId}> |
| 99 | + <td class='col-md-1' textContent={rowId} /> |
| 100 | + <td class='col-md-4'><a onClick={({currentTarget: t}) => { selected.value = t.closest('tr') }} textContent={ label.value } /></td> |
| 101 | + <td class='col-md-1'><a onClick={() => { remove(idx) }}><span class='glyphicon glyphicon-remove' aria-hidden='true' /></a></td> |
| 102 | + <td class='col-md-6'/> |
| 103 | + </tr> |
| 104 | + ))} |
| 105 | + </tbody></table> |
| 106 | + <span class='preloadicon glyphicon glyphicon-remove' aria-hidden='true' /> |
| 107 | + </div> |
| 108 | +); |
| 109 | + |
| 110 | +render(<App />, document.getElementById("main")); |
0 commit comments