widgets.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. use dioxus_html::HasFormData;
  2. use dioxus_native_core::{
  3. prelude::*,
  4. real_dom::{NodeImmutable, NodeTypeMut},
  5. NodeId,
  6. };
  7. use plasmo::{render, Config, Driver, EventData};
  8. use std::rc::Rc;
  9. use std::sync::{Arc, RwLock};
  10. #[derive(Default)]
  11. struct Counter {
  12. count: f64,
  13. button_id: NodeId,
  14. }
  15. impl Counter {
  16. fn create(mut root: NodeMut) -> Self {
  17. let mut myself = Self::default();
  18. let root_id = root.id();
  19. let rdom = root.real_dom_mut();
  20. // create the counter
  21. let count = myself.count;
  22. let mut button = rdom.create_node(NodeType::Element(ElementNode {
  23. tag: "input".to_string(),
  24. attributes: [
  25. // supported types: button, checkbox, textbox, password, number, range
  26. ("type".to_string().into(), "range".to_string().into()),
  27. ("display".to_string().into(), "flex".to_string().into()),
  28. (("flex-direction", "style").into(), "row".to_string().into()),
  29. (
  30. ("justify-content", "style").into(),
  31. "center".to_string().into(),
  32. ),
  33. (("align-items", "style").into(), "center".to_string().into()),
  34. (
  35. "value".to_string().into(),
  36. format!("click me {count}").into(),
  37. ),
  38. (("width", "style").into(), "50%".to_string().into()),
  39. (("height", "style").into(), "10%".to_string().into()),
  40. ("min".to_string().into(), "20".to_string().into()),
  41. ("max".to_string().into(), "80".to_string().into()),
  42. ]
  43. .into_iter()
  44. .collect(),
  45. ..Default::default()
  46. }));
  47. button.add_event_listener("input");
  48. myself.button_id = button.id();
  49. rdom.get_mut(root_id).unwrap().add_child(myself.button_id);
  50. myself
  51. }
  52. }
  53. impl Driver for Counter {
  54. fn update(&mut self, rdom: &Arc<RwLock<RealDom>>) {
  55. // update the counter
  56. let mut rdom = rdom.write().unwrap();
  57. let mut node = rdom.get_mut(self.button_id).unwrap();
  58. if let NodeTypeMut::Element(mut el) = node.node_type_mut() {
  59. el.set_attribute(
  60. ("background-color", "style"),
  61. format!("rgb({}, {}, {})", 255.0 - self.count * 2.0, 0, 0,),
  62. );
  63. };
  64. }
  65. fn handle_event(
  66. &mut self,
  67. _: &Arc<RwLock<RealDom>>,
  68. _: NodeId,
  69. event_type: &str,
  70. event: Rc<EventData>,
  71. _: bool,
  72. ) {
  73. if event_type == "input" {
  74. // when the button is clicked, increment the counter
  75. if let EventData::Form(input_event) = &*event {
  76. if let Ok(value) = input_event.value().parse::<f64>() {
  77. self.count = value;
  78. }
  79. }
  80. }
  81. }
  82. fn poll_async(&mut self) -> std::pin::Pin<Box<dyn futures::Future<Output = ()> + '_>> {
  83. Box::pin(async move { tokio::time::sleep(std::time::Duration::from_millis(1000)).await })
  84. }
  85. }
  86. fn main() {
  87. render(Config::new(), |rdom, _, _| {
  88. let mut rdom = rdom.write().unwrap();
  89. let root = rdom.root_id();
  90. Counter::create(rdom.get_mut(root).unwrap())
  91. })
  92. .unwrap();
  93. }