github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/examples/todoapp/todo_app.go (about)

     1  package todoapp // import "myitcv.io/react/examples/todoapp"
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"honnef.co/go/js/dom"
     7  	"myitcv.io/react"
     8  )
     9  
    10  //go:generate reactGen
    11  
    12  // TodoAppDef is the definition fo the TodoApp component
    13  type TodoAppDef struct {
    14  	react.ComponentDef
    15  }
    16  
    17  // TodoAppState is the state type for the TodoApp component
    18  type TodoAppState struct {
    19  	items    []string
    20  	currItem string
    21  }
    22  
    23  // TodoApp creates instances of the TodoApp component
    24  func TodoApp() *TodoAppElem {
    25  	return buildTodoAppElem()
    26  }
    27  
    28  // Equals must be defined because struct val instances of TodoAppState cannot
    29  // be compared. It is generally bad practice to have mutable values in state in
    30  // this way; myitcv.io/immutable seeks to help address this problem.
    31  // See myitcv.io/react/examples/immtodoapp for an example
    32  func (c TodoAppState) Equals(v TodoAppState) bool {
    33  	if c.currItem != v.currItem {
    34  		return false
    35  	}
    36  
    37  	if len(v.items) != len(c.items) {
    38  		return false
    39  	}
    40  
    41  	for i := range v.items {
    42  		if v.items[i] != c.items[i] {
    43  			return false
    44  		}
    45  	}
    46  
    47  	return true
    48  }
    49  
    50  // Render renders the TodoApp component
    51  func (t TodoAppDef) Render() react.Element {
    52  	var entries []react.RendersLi
    53  
    54  	for _, v := range t.State().items {
    55  		entry := react.Li(nil, react.S(v))
    56  		entries = append(entries, entry)
    57  	}
    58  
    59  	return react.Fragment(
    60  		react.H3(nil, react.S("TODO")),
    61  		react.Ul(nil, entries...),
    62  		react.Form(&react.FormProps{ClassName: "form-inline"},
    63  			react.Div(
    64  				&react.DivProps{ClassName: "form-group"},
    65  				react.Label(&react.LabelProps{ClassName: "sr-only", For: "todoText"}, react.S("Todo Item")),
    66  				react.Input(&react.InputProps{
    67  					Type:        "text",
    68  					ClassName:   "form-control",
    69  					ID:          "todoText",
    70  					Placeholder: "Todo Item",
    71  					Value:       t.State().currItem,
    72  					OnChange:    inputChange{t},
    73  				}),
    74  				react.Button(&react.ButtonProps{
    75  					Type:      "submit",
    76  					ClassName: "btn btn-default",
    77  					OnClick:   add{t},
    78  				}, react.S(fmt.Sprintf("Add #%v", len(t.State().items)+1))),
    79  			),
    80  		),
    81  	)
    82  }
    83  
    84  type inputChange struct{ t TodoAppDef }
    85  type add struct{ t TodoAppDef }
    86  
    87  func (i inputChange) OnChange(se *react.SyntheticEvent) {
    88  	target := se.Target().(*dom.HTMLInputElement)
    89  
    90  	ns := i.t.State()
    91  	ns.currItem = target.Value
    92  
    93  	i.t.SetState(ns)
    94  }
    95  
    96  func (a add) OnClick(se *react.SyntheticMouseEvent) {
    97  	ns := a.t.State()
    98  	ns.items = append(ns.items, ns.currItem)
    99  	ns.currItem = ""
   100  
   101  	a.t.SetState(ns)
   102  
   103  	se.PreventDefault()
   104  }