Mithril with MaterializeCSS
HTML
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/materialize/0.97.3/css/materialize.min.css">
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/materialize/0.97.3/js/materialize.min.js"></script>
<div class="container" id="main">
<div class="row">
<div class="col s12 m7">
<div id="root"></div>
</div>
</div>
</div>
CSS
#main{margin-top: 20px;}
#root{margin-top: 30px;}
.form-control{margin-bottom: 10px;}
body{font-family: Helvetica;}
CoffeeScript
## https://gist.github.com/impinball/5e4d6e64aba2ffb7cd23
## Patches Mithril to accept components as well as strings
@m = ((o) ->
Object.assign (->
(if typeof arguments[0] == 'string' then o else o.component).apply undefined, arguments
), o
)(m)
Collection =
view: (ctrl, props) ->
m 'ul.collection', props.map (d) -> m CollectionItem, d
CollectionItem =
view: (ctrl, props) ->
m 'li.collection-item avatar',
m 'span.title', props.title
m 'p', props.description.map (d) ->
m 'span', d, m 'br'
myCollection = (N) ->
[1..N].map (d, i) ->
src: "https://placeimg.com/200/200"
title: "Card #{i}"
description: ["Description", "Line " + d]
CardImage =
view: (ctrl, props) ->
m '.card-image', [
m 'img', {src: props.img}
m 'span.card-title', props.title
]
CardContent =
view: (ctrl, props) ->
m '.card-content', m('p', props.description)
CardAction =
view: (ctrl, props) ->
m '.card-action', m('a[href="#"]', props.action)
Card =
view: (ctrl, props) ->
m '.card', [
m CardImage, {img: props.img, title: props.title}
m CardContent, {description: props.description}
m CardAction, {action: props.action}
]
#run the app
###
m.mount(
document.getElementById("root"),
m Card, {
img: "https://placeimg.com/300/200/any"
title: "Card Title"
description: """
I am a very simple card. I am good at containing small bits of information. I am convenient because
I require little markup to use effectively.
"""
action: "This is a link"
}
)
###
App =
controller: ->
N: m.prop(3)
view: (ctrl, props) ->
m 'div',
m 'div.input-field',
m 'input[type="number"]', {
onchange: m.withAttr("value", ctrl.N)
value: ctrl.N()
class: 'validate'
}
m Collection, myCollection(ctrl.N())
m.mount(
document.getElementById("root"),
m App
)