-
-
Save mrjjwright/5dbb76c925cd676e9c4a to your computer and use it in GitHub Desktop.
Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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