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
)