Skip to content

Instantly share code, notes, and snippets.

@mrjjwright
Last active August 29, 2015 14:21
Show Gist options
  • Save mrjjwright/5dbb76c925cd676e9c4a to your computer and use it in GitHub Desktop.
Save mrjjwright/5dbb76c925cd676e9c4a to your computer and use it in GitHub Desktop.
Playground
h = snabbdom.h
patch = snabbdom.patch
{map, flatten, union, first, tail, each, keys, is-type, empty} = require 'prelude-ls'
obj-is-el = ->
return true if is-type 'Array', it
return it.elm?
is-node = ->
switch typeof it
| 'number' => true
| 'string' => true
| 'boolean' => !it
| 'object' => obj-is-el it
| otherwise false
component = (el, args) ->
props = first args or {}
children = tail args
if is-node props
children = args
props = {}
theChildren =
unless empty children
flatten children
h el, props, theChildren
vdom = (el) ->
(...args) ->
component el, args
domElements = ['div', 'ul', 'input', 'textArea', 'select', 'span', 'a', 'img']
each (-> vdom[it] = vdom it), domElements
# Our main streams
const appStarted$ = flyd.stream()
const appRender$ = flyd.stream()
const workAreaRender$ = flyd.stream()
const inspectorRender$ = flyd.stream()
const workItem$ = flyd.stream()
const newItem$ = flyd.stream()
const selectedItem$ = flyd.stream()
basics = ->
view:
style:
border: "1px solid blue"
display: \flex
width: \100
height: \100
div:
style:
border: "1px solid blue"
display: \flex
width: \100
height: \100
img:
src: ""
style:
display: \flex
width: \100
height: \100
appStarted$.map ->
# Create a batch to be rendered
pickerItems =
\play
\div
\img
appRender$ do
vdom.div do
style:
backgroundColor: \white
display: "flex"
flexDirection: \row
vdom.div do
id: \outline
style:
backgroundColor: \white
display: \flex
flexDirection: \column
flex: \2
borderRightStyle: \solid
borderRightWidth: 1
borderRightColor: \blue
vdom.div do
id: \tree
style:
flex: 4
vdom.div do
id: \picker
style:
flex: 3
display: \flex
flexDirection: \row
borderTopStyle: \solid
borderTopWidth: 1
borderTopColor: \blue
pickerItems
|> map ->
vdom.div do
* onclick: [newItem$, it]
style:
width: 150
height: 50
backgroundColor: \white
flex: 1
it
vdom.div do
id: \workArea
style:
backgroundColor: \white
display: \flex
flex: \4
vdom.div do
id: "workAreaItem"
oninsert: ->
flyd.scan patch, snabbdom.emptyNodeAt(it.elm), workAreaRender$
vdom.div do
id: \inspector
oninsert: ->
flyd.scan patch, snabbdom.emptyNodeAt(it.elm), inspectorRender$
style:
display: \flex
flex: 2
flexDirection: \column
borderLeftStyle: \solid
borderLeftWidth: 1
borderLeftColor: \blue
window.addEventListener 'DOMContentLoaded', ->
container = document.getElementById 'container'
flyd.scan patch, snabbdom.emptyNodeAt(container), appRender$
appStarted$ 'Play Started'
# Render the workArea when the workItem changes
workItem$.map ->
workAreaRender$ it
# Render the inspector when the selectedItem changes
selectedItem$.map ->
inspectorRender$ inspectorView it
newItem$.map ->
newItem = vdom[it] basics![it]
if workItem$!?
then
currentItem = R.clone workItem$!
currentItem.children = [] unless currentItem.children?
currentItem.children.push newItem
workItem$ currentItem
selectedItem$ currentItem
else
workItem$ newItem
selectedItem$ newItem
styleProps =
\backgroundColor
\flex
\flexDirection
\width
\height
imgProps = [\src]
inspectorView = (item) ->
itemView = (prop, value, updater) ->
vdom.div do
style:
display: \flex
flexDirection: \row
padding: 5
vdom.span do
* style:
width: 150
prop
vdom.input do
type: \text
onchange: (e) ->
updatedWorkItem = deepmerge selectedItem$!, props: updater(e)
selectedItem$ updatedWorkItem
value: value
style:
marginLeft: 8
width: 120
height: 22
vdom.div do
map (-> itemView it, item.props.style[it], (e) -> style: (it): e.target.value), styleProps
if item.tag is \img
then map (-> itemView it, item.props[it], (e) -> (it): e.target.value), imgProps
else ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment