Skip to content

Instantly share code, notes, and snippets.

@ZucchiniZe
Created July 7, 2017 05:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZucchiniZe/3327a910a5fc2066fc909646c948a5be to your computer and use it in GitHub Desktop.
Save ZucchiniZe/3327a910a5fc2066fc909646c948a5be to your computer and use it in GitHub Desktop.
let pluralize ::word numItems::items => {
if (items != 1) {
(string_of_int items) ^ " " ^ word ^ "s";
} else {
(string_of_int items) ^ " " ^ word;
}
};
type item = {
id: int,
title: string,
completed: bool
};
let se = ReasonReact.stringToElement;
let module TodoItem = {
let component = ReasonReact.statelessComponent "TodoItem";
let make ::item ::onToggle _children => {
...component,
render: fun _self => {
<div className="item" onClick=(fun _evt => onToggle())>
<input
_type="checkbox"
checked=(Js.Boolean.to_js_boolean item.completed)
/>
(se item.title)
</div>
}
};
};
let valueFromEvent evt: string =>
(evt
|> ReactEventRe.Form.target
|> ReactDOMRe.domElementToObj
)##value;
let module Input = {
type state = string;
let component = ReasonReact.statefulComponent "Input";
let make ::onSubmit _self => {
...component,
initialState: fun () => "",
render: fun {state: text, update} => {
<input
value=text
_type="text"
placeholder="Write something to do"
onChange=(update (fun evt _ =>
ReasonReact.Update (valueFromEvent evt)
))
onKeyDown=(update (fun evt {state: text} =>
if (ReactEventRe.Keyboard.key evt == "Enter") {
onSubmit text;
ReasonReact.Update "";
} else {
ReasonReact.NoUpdate
}
))
/>
}
}
};
type state = {
items: list item,
};
let component = ReasonReact.statefulComponent "TodoApp";
let lastId = ref 0;
let newItem text => {
lastId := !lastId + 1;
{id: !lastId, title: text, completed: true};
};
let toggleItem items id => {
List.map
(fun item => item.id === id
? {...item, completed: not item.completed}
: item)
items;
};
let make _children => {
...component,
initialState: fun () => {
items: [{
id: 0,
title: "Write somethings to do",
completed: false,
}]
},
render: fun {state: {items}, update} => {
<div className="app">
<div className="title">
(se "What to do")
<Input
onSubmit=(update (fun text {state} => {
ReasonReact.Update {
items: [newItem text, ...state.items]
}
}))
/>
</div>
<div className="items">
(List.map (fun item => <TodoItem
key=(string_of_int item.id)
onToggle=(update (fun _ {state} =>
ReasonReact.Update {
items: toggleItem items item.id
}
))
item />) items
|> Array.of_list
|> ReasonReact.arrayToElement )
</div>
<div className="footer">
(se (pluralize word::"item" numItems::(List.length items)))
</div>
</div>
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment