1
0

control_focus.rs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. //! Managing focus
  2. //!
  3. //! This example shows how to manage focus in a Dioxus application. We implement a "roulette" that focuses on each input
  4. //! in the grid every few milliseconds until the user interacts with the inputs.
  5. use dioxus::prelude::*;
  6. use std::rc::Rc;
  7. const STYLE: &str = asset!(file("./examples/assets/roulette.css"));
  8. fn main() {
  9. launch_desktop(app);
  10. }
  11. fn app() -> Element {
  12. // Element data is stored as Rc<MountedData> so we can clone it and pass it around
  13. let mut elements = use_signal(Vec::<Rc<MountedData>>::new);
  14. let mut running = use_signal(|| true);
  15. use_future(move || async move {
  16. let mut focused = 0;
  17. loop {
  18. tokio::time::sleep(std::time::Duration::from_millis(50)).await;
  19. if !running() {
  20. continue;
  21. }
  22. if let Some(element) = elements.with(|f| f.get(focused).cloned()) {
  23. _ = element.set_focus(true).await;
  24. } else {
  25. focused = 0;
  26. }
  27. focused += 1;
  28. }
  29. });
  30. rsx! {
  31. link { rel: "stylesheet", href: STYLE }
  32. h1 { "Input Roulette" }
  33. button { onclick: move |_| running.toggle(), "Toggle roulette" }
  34. div { id: "roulette-grid",
  35. // Restart the roulette if the user presses escape
  36. onkeydown: move |event| {
  37. if event.code().to_string() == "Escape" {
  38. running.set(true);
  39. }
  40. },
  41. // Draw the grid of inputs
  42. for i in 0..100 {
  43. input {
  44. r#type: "number",
  45. value: "{i}",
  46. onmounted: move |cx| elements.write().push(cx.data()),
  47. oninput: move |_| running.set(false),
  48. }
  49. }
  50. }
  51. }
  52. }