Readable and Writable helpers for String, HashMap and HashSet (#4834)

* Add more read/write methods for string signals

* add helpers for HashMap and HashSet as well

* fix typo

* fix conflicting string and str extensions

* fix counters example
This commit is contained in:
Evan Almloff authored and GitHub committed 2025-10-27 11:39:48 -07:00
1 parent 3eecfaa0a7
commit e4297d0e09
13 files changed
+308 -33

No files matched your search

+4 -4
View File
@@ -34,15 +34,15 @@ fn app() -> Element {
if val() == "0" {
val.set(String::new());
}
val.write().push_str(num.as_str());
val.push_str(num.as_str());
};
let mut input_operator = move |key: &str| val.write().push_str(key);
let mut input_operator = move |key: &str| val.push_str(key);
let handle_key_down_event = move |evt: KeyboardEvent| match evt.key() {
Key::Backspace => {
if !val().is_empty() {
val.write().pop();
val.pop();
}
}
Key::Character(character) => match character.as_str() {
@@ -104,7 +104,7 @@ fn app() -> Element {
}
button {
class: "calculator-key key-dot",
onclick: move |_| val.write().push('.'),
onclick: move |_| val.push('.'),
"●"
}
for k in 1..10 {
+3 -3
View File
@@ -19,8 +19,8 @@ fn app() -> Element {
Stylesheet { href: STYLE }
div { id: "controls",
button { onclick: move |_| counters.write().push(0), "Add counter" }
button { onclick: move |_| { counters.write().pop(); }, "Remove counter" }
button { onclick: move |_| counters.push(0), "Add counter" }
button { onclick: move |_| { counters.pop(); }, "Remove counter" }
}
h3 { "Total: {sum}" }
@@ -47,7 +47,7 @@ fn app() -> Element {
}
}
button { onclick: move |_| counters.write()[i] += 1, "+1" }
button { onclick: move |_| { counters.write().remove(i); }, "x" }
button { onclick: move |_| { counters.remove(i); }, "x" }
}
}
}
+6 -6
View File
@@ -115,13 +115,13 @@ fn TodoHeader(mut todos: WriteSignal<HashMap<u32, TodoItem>>) -> Element {
let mut todo_id = use_signal(|| 0);
let onkeydown = move |evt: KeyboardEvent| {
if evt.key() == Key::Enter && !draft.read().is_empty() {
if evt.key() == Key::Enter && !draft.is_empty() {
let id = todo_id();
let todo = TodoItem {
checked: false,
contents: draft.to_string(),
};
todos.write().insert(id, todo);
todos.insert(id, todo);
todo_id += 1;
draft.set("".to_string());
}
@@ -169,7 +169,7 @@ fn TodoEntry(mut todos: WriteSignal<HashMap<u32, TodoItem>>, id: u32) -> Element
r#type: "checkbox",
id: "cbg-{id}",
checked: "{checked}",
oninput: move |evt| todos.write().get_mut(&id).unwrap().checked = evt.checked()
oninput: move |evt| todos.get_mut(&id).unwrap().checked = evt.checked()
}
label {
r#for: "cbg-{id}",
@@ -181,7 +181,7 @@ fn TodoEntry(mut todos: WriteSignal<HashMap<u32, TodoItem>>, id: u32) -> Element
class: "destroy",
onclick: move |evt| {
evt.prevent_default();
todos.write().remove(&id);
todos.remove(&id);
},
}
}
@@ -191,7 +191,7 @@ fn TodoEntry(mut todos: WriteSignal<HashMap<u32, TodoItem>>, id: u32) -> Element
input {
class: "edit",
value: "{contents}",
oninput: move |evt| todos.write().get_mut(&id).unwrap().contents = evt.value(),
oninput: move |evt| todos.get_mut(&id).unwrap().contents = evt.value(),
autofocus: "true",
onfocusout: move |_| is_editing.set(false),
onkeydown: move |evt| {
@@ -250,7 +250,7 @@ fn ListFooter(
if show_clear_completed() {
button {
class: "clear-completed",
onclick: move |_| todos.write().retain(|_, todo| !todo.checked),
onclick: move |_| todos.retain(|_, todo| !todo.checked),
"Clear completed"
}
}
+1 -1
View File
@@ -175,7 +175,7 @@ fn TodoHeader(mut todos: Store<TodoState>) -> Element {
let mut todo_id = use_signal(|| 0);
let onkeydown = move |evt: KeyboardEvent| {
if evt.key() == Key::Enter && !draft.read().is_empty() {
if evt.key() == Key::Enter && !draft.is_empty() {
let id = todo_id();
let todo = TodoItem::new(draft.take());
todos.todos().insert(id, todo);
+1 -1
View File
@@ -46,7 +46,7 @@ fn app() -> Element {
use_future(move || async move {
while let Ok(msg) = socket.recv().await {
match msg {
ServerEvent::ReceiveMessage(message) => message_list.write().push(message),
ServerEvent::ReceiveMessage(message) => message_list.push(message),
ServerEvent::Connected { messages } => message_list.set(messages),
}
}