Skip to content

Instantly share code, notes, and snippets.

@bloodyowl
Created January 4, 2017 15:16
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bloodyowl/0529e7165aff4519f245c0f5f4872d34 to your computer and use it in GitHub Desktop.
Save bloodyowl/0529e7165aff4519f245c0f5f4872d34 to your computer and use it in GitHub Desktop.
Component library in less than 140 bytes
b=0;$=x=>(p,i="_"+b++,u=($[i]=q=>eval(i).innerHTML=x(p,$[q],u),z=>($[++b]=z,`$.${i}(${b})`)))=>`<c id=${i}>${x(p,[]._,u)}</c>`
b = 0; // global ID
$ = // component
x => // render function
(
p, // props
i = "_" + b++, // id
u = (
// updater = nextStateID => document.getElementById(id).innerHTML = render(props, states[nextStateID], update)
$[i] = q => eval(i).innerHTML = x(p, $[q], u),
// nextState => { id = nuid(); states[id] = nextState; return () => updater(id) }
z => (
$[++b] = z,
`$.${i}(${ b })`
)
)
// return the contents
) => `<c id=${i}>${ x(p, []._, u) }</c>`
// Test at https://jsfiddle.net/bloodyowl/hkpbtmbo/
const DecrementButton = $(props =>
`<div>
<button onclick="${ props.decrement }">decrement</button>
</div>`
)
const IncrementButton = $(props =>
`<div>
<button onclick="${ props.increment }">increment</button>
</div>`
)
const App = $((props, state = 0, update) =>
`<div>
<b>${ state }</b>
${ IncrementButton({ increment: update(state + 1) }) }
${ state === 0 ? `` : DecrementButton({ decrement: update(state - 1) }) }
</div>`
)
document.body.innerHTML = App({})
@bloodyowl
Copy link
Author

screen recording 2017-01-04 at 04 15 pm

@bloodyowl
Copy link
Author

b=0;$=x=>(p,i=p.key||"_"+b++,u=($[i]=q=>eval(i).innerHTML=x(p,$[0+i]=$[q],u),z=>($[++b]=z,`$.${i}(${b})`)))=>`<c id=${i}>${x(p,$[0+i],u)}</c>`

With a 142 bytes version, you can nest stateful components (by giving them a globally unique key)

@FWeinb
Copy link

FWeinb commented Jan 4, 2017

b=0;$=x=>(p,i="_"+b++,u=($[i]=q=>eval(i).innerHTML=x(p,$[q],u),z=>`$.${i}(${$[++b]=z,b})`))=>`<c id=${i}>${x(p,[]._,u)}`

Inlining $[++b] = z into ${} make it possible to remove two chars. Leaving of </c> gets this down to 121 bytes.

@robinpokorny
Copy link

robinpokorny commented Jan 5, 2017

b._ for undefined is one letter shorter than []._ 😄

@robinpokorny
Copy link

A small, small improvement would be to replace

$[++b] = z,
  `$.${i}(${ b })`

with

$[b] = z,
  `$.${i}(${ b++ })`

Since now 'components' and 'nextState' ID's can overlap. So after click on 'increment', Object.keys($) return

["2", "3", "5", "6", "8", "_0", "_3", "_6", "_8"]

With changed code and after clicking on 'increment', Object.keys($) would return

["1", "2", "4", "5", "7", "_0", "_3", "_6", "_8"]

WDYT?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment