all imlementations using CycleJS all imlementations of Twoway

an xstream implementation
of the Twoway demo using CycleJS



import xs from 'xstream'
import {div, input, p, button} from '@cycle/dom'

function Phonebooth ({DOM}) {
  const type$ = DOM.select('input')
    .events('input')
    .map(e => e.target.value)
    .startWith('Steve')
  const click$ = DOM.select('button')
    .events('click')
    .mapTo('Batman')
  return {
    DOM: xs.merge(type$, click$).map(name => div([
      input({props: {value: name}}),
      p(['Your name is ' + name + '.']),
      button(['Put on costume'])
    ])),
    focus: click$
  }
}

export default Phonebooth

The same file in a TypeScript implementation using Angular (2.4.9):

import {Component,ViewChild} from '@angular/core';

@Component({
  selector: '#app',
  template: `
    <input #field [(ngModel)]="name"><br/>
    <p>Your name is {{name}}.</p>
    <button (click)="change()">Put on costume</button>
  `
})
export class Phonebooth {
  @ViewChild('field') input
  name = 'Steve'
  change() {
    this.name = 'Batman'
    this.input.nativeElement.focus()
  }
}

The same file in a component implementation using AngularJS (1.5.8):

import angular from 'angular'

angular.module('phoneboothapp')
  .component('phonebooth', {
    template: `
      <input ng-model="$ctrl.name"><br/>
      <p>Your name is {{$ctrl.name}}.</p>
      <button ng-click="$ctrl.change()">Put on costume</button>
    `,
    controller: class Phonebooth {
      constructor ($element) {
        this.field = $element.find('input')[0]
        this.name = 'Steve'
      }
      change () {
        this.name = 'Batman'
        this.field.focus()
      }
    }
  })

The same file in an es6 implementation using Cyclow (0.5.0):

import {Block} from 'cyclow'

const Phonebooth = () => Block({
  on: {
    'in.init': () => state => ({name: 'Steve'}),
    'dom.text': text => state => ({name: text}),
    'dom.click': () => ({
      state: () => ({name: 'Batman'}),
      'dom.action': el => el.firstElementChild.focus()
    })
  },
  view: ({name}) => ({
    attrs: {id: 'app'},
    content: [
      {
        tag: 'input',
        attrs: {value: name},
        on: {keyup: (e, next) => next({text: e.target.value})}
      },
      {tag: 'p', content: `Your name is ${name}.`},
      {tag: 'button', content: 'Put on costume', on: {click: 'click'}}
    ]
  })
})

export default Phonebooth

The same file in a react-elm-components implementation using Elm (0.17.1):

port module Phonebooth exposing (main)

import Html exposing (Html, Attribute, div, input, text, button, p)
import Html.App as App
import Html.Attributes exposing (..)
import Html.Events exposing (onInput, onClick)


main =
    App.beginnerProgram { model = model, view = view, update = update }



-- MODEL


type alias Model =
    { name : String
    }


model : Model
model =
    { name = "Steve" }



-- UPDATE


type Msg
    = ChangeName String
    | SuitUp


update : Msg -> Model -> Model
update msg model =
    case msg of
        ChangeName newName ->
            { model | name = newName }

        SuitUp ->
            { name = "Batman" }



-- VIEW


view : Model -> Html Msg
view model =
    div []
        [ div [] [ input [ onInput ChangeName, value model.name ] [] ]
        , p []
            [ text "Your name is "
            , text model.name
            ]
        , button [ onClick SuitUp ] [ text "Put on costume" ]
        ]

The same file in a createClass implementation using React (15.3.1):

import React from 'react'

let Phonebooth = React.createClass({
  getInitialState: () => ({name: 'Steve'}),
  change () {
    this.setState({name: 'Batman'})
    this.refs.field.focus()
  },
  type (e) {
    this.setState({name: e.target.value})
  },
  render () {
    let name = this.state.name
    return <div>
      <div><input ref='field' onChange={this.type} value={name} /></div>
      <p>Your name is {name}</p>
      <button onClick={this.change}>Put on costume</button>
    </div>
  }
})

export default Phonebooth

The same file in a vanilla implementation using Vue (1.0.26):

import Vue from 'vue'

Vue.component('phonebooth', {
  template: `
    <input v-model="name" v-el:input><br/>
    <p>Your name is {{name}}.</p>
    <button v-on:click="change">Put on costume</button>
  `,
  data: () => ({name: 'Steve'}),
  methods: {
    change () {
      this.name = 'Batman'
      this.$els.input.focus()
    }
  }
})