control_focus.rs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  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 std::rc::Rc;
  6. use async_std::task::sleep;
  7. use dioxus::prelude::*;
  8. const STYLE: Asset = asset!("/examples/assets/roulette.css");
  9. fn main() {
  10. dioxus::launch(app);
  11. }
  12. fn app() -> Element {
  13. // Element data is stored as Rc<MountedData> so we can clone it and pass it around
  14. let mut elements = use_signal(Vec::<Rc<MountedData>>::new);
  15. let mut running = use_signal(|| true);
  16. use_future(move || async move {
  17. let mut focused = 0;
  18. loop {
  19. sleep(std::time::Duration::from_millis(50)).await;
  20. if !running() {
  21. continue;
  22. }
  23. if let Some(element) = elements.with(|f| f.get(focused).cloned()) {
  24. _ = element.set_focus(true).await;
  25. } else {
  26. focused = 0;
  27. }
  28. focused += 1;
  29. }
  30. });
  31. rsx! {
  32. document::Link { rel: "stylesheet", href: STYLE }
  33. h1 { "Input Roulette" }
  34. button { onclick: move |_| running.toggle(), "Toggle roulette" }
  35. div { id: "roulette-grid",
  36. // Restart the roulette if the user presses escape
  37. onkeydown: move |event| {
  38. if event.code().to_string() == "Escape" {
  39. running.set(true);
  40. }
  41. },
  42. // Draw the grid of inputs
  43. for i in 0..100 {
  44. input {
  45. r#type: "number",
  46. value: "{i}",
  47. onmounted: move |cx| elements.write().push(cx.data()),
  48. oninput: move |_| running.set(false),
  49. }
  50. }
  51. }
  52. }
  53. }