Last active
June 19, 2020 05:58
-
-
Save rebo/a556debf7b7508293d52bede5e1856cc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Clone)] | |
struct Todo{ | |
idx: usize, | |
description: String, | |
complete: bool, | |
} | |
// Atom of state, a vector holding Todo structs | |
#[state] | |
fn todos()-> Vec<Todo>{ | |
vec![] | |
} | |
#[derive(Clone, PartialEq)] | |
enum FilterStatus { | |
ShowAll, | |
Complete, | |
Incomplete, | |
} | |
// The state of the chosen filter method, defaults to show all | |
#[state] | |
fn filter_state()-> FilterStatus { | |
FilterStatus::ShowAll | |
} | |
// Automatically computes filtered todos when (and only when todos are updated) | |
#[computed] | |
fn filtered_todos() -> Vec<Todo> { | |
let todos = link_state(todos()); | |
let filter = link_state(filter_state()); | |
match filter { | |
FilterStatus::ShowAll => todos, | |
FilterStatus::Complete => todos.iter().filter(|t| t.complete).cloned().collect::<Vec<_>>(), | |
FilterStatus::Incomplete => todos.iter().filter(|t| !t.complete).cloned().collect::<Vec<_>>(), | |
} | |
} | |
// Automatically generates a show-all button dependent upon the filter state | |
#[computed] | |
fn show_all_button() -> Node<Msg> { | |
let filter = link_state(filter_state()); | |
fancy_button![ | |
if filter == FilterStatus::ShowAll{ | |
s().bg_color(rgb(0,255,0)).font_weight_v900() | |
} else { | |
s().bg_color(rgb(180,120,120)) | |
}, | |
"Show All", | |
mouse_ev(Ev::Click, |_| | |
filter_state().update(|s| *s = FilterStatus::ShowAll ) | |
) | |
] | |
} | |
// Automatically generates a show-complete button dependent upon the filter state | |
#[computed] | |
fn show_complete_button() -> Node<Msg> { | |
let filter == link_state(filter_state()); | |
fancy_button![ | |
if filter = FilterStatus::Complete { | |
s().bg_color(rgb(0,255,0)).font_weight_v900() | |
} else { | |
s().bg_color(rgb(180,120,120)) | |
}, | |
"Show Complete", | |
mouse_ev(Ev::Click, |_| | |
filter_state().update(|s| *s = FilterStatus::Complete) | |
) | |
] | |
} | |
// Automatically generates a show-incomplete button snippet dependent upon the filter state | |
#[computed] | |
fn show_incomplete_button() -> Node<Msg> { | |
let filter = link_state(filter_state()); | |
fancy_button![ | |
if filter == FilterStatus::Incomplete{ | |
s().bg_color(rgb(0,255,0)).font_weight_v900() | |
} else { | |
s().bg_color(rgb(180,120,120)) | |
}, | |
"Show Incomplete", | |
mouse_ev(Ev::Click, |_| | |
filter_state().update(|s| *s = FilterStatus::Incomplete) | |
) | |
] | |
} | |
// Input state for the button element, defaults to empty string | |
#[state] | |
fn todo_input_state() -> String { | |
"".to_string() | |
} | |
// Main view a column of items. Title, Input, Controls, then Todos. | |
pub fn view(_model: &Model) -> Node<Msg> { | |
Column![ | |
Item![ | |
align = ColumnAlign::TopCenter, | |
h1!["Todos"] | |
], | |
Item![ | |
align = ColumnAlign::TopCenter, | |
flex = Flex::None, | |
input![ | |
attrs!(At::Value => todo_input_state().get()), | |
s().b_style_solid().b_width(px(1)).b_color(seed_colors::Gray::No7), | |
input_ev(Ev::Input, |s| todo_input_state().update(|t| *t = s)) | |
], | |
fancy_button![ | |
s().bg_color(seed_colors::Blue::No4), | |
"Add Todo", | |
mouse_ev(Ev::Click, |_| | |
// if "add todo" is pressed then update the "todos" atom state. | |
// and clear the input atom state | |
todos().update(|t|{ | |
t.push( | |
Todo { | |
idx: t.len(), | |
description: todo_input_state().get(), | |
complete: false, | |
} | |
); | |
todo_input_state().update(|t| | |
*t = "".to_string() | |
) | |
}) | |
) | |
] | |
], | |
Item![ | |
align = ColumnAlign::TopCenter, | |
flex = Flex::None, | |
show_all_button().get(), | |
show_complete_button().get(), | |
show_incomplete_button().get() | |
], | |
Item![ | |
align = ColumnAlign::TopCenter, | |
filtered_todos().get().iter().map(|todo| { | |
let todo_idx = todo.idx; | |
li![ | |
s().display_flex().justify_content_flex_end().align_content_center(), | |
center![todo.description.clone()], | |
fancy_button![ | |
if todo.complete{ | |
s().bg_color(seed_colors::Green::No4) | |
} else { | |
s().bg_color(seed_colors::Gray::No4) | |
} | |
,"X", | |
mouse_ev(Ev::Click, move |_| { | |
todos().update(|ts| | |
for t in ts.iter_mut(){ | |
if t.idx == todo_idx {t.complete = !t.complete} | |
} | |
) | |
}) | |
] | |
] | |
} | |
) | |
] | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment