wasm_react/props/
props.rs1use crate::{
2 hooks::{use_tmp_ref, JsRefContainer},
3 Callback, KeyType,
4};
5use js_sys::{Object, Reflect};
6use wasm_bindgen::{
7 convert::{FromWasmAbi, IntoWasmAbi, OptionFromWasmAbi},
8 intern, JsCast, JsValue, UnwrapThrowExt,
9};
10
11#[derive(Debug, Default, Clone)]
30pub struct Props(Object);
31
32impl Props {
33 pub fn new() -> Self {
35 Self::default()
36 }
37
38 pub fn key(self, value: Option<impl KeyType>) -> Self {
42 self.insert(
43 "key",
44 &value.map(|x| x.into()).unwrap_or(JsValue::UNDEFINED),
45 )
46 }
47
48 pub fn ref_container<T>(self, ref_container: &JsRefContainer<T>) -> Self {
53 self.insert("ref", ref_container.as_ref())
54 }
55
56 pub fn ref_callback<T>(self, ref_callback: &Callback<Option<T>>) -> Self
60 where
61 T: OptionFromWasmAbi + 'static,
62 {
63 self.insert_callback("ref", ref_callback)
64 }
65
66 pub fn insert(self, key: &str, value: &JsValue) -> Self {
68 self.ref_insert(key, value);
69 self
70 }
71
72 fn ref_insert(&self, key: &str, value: &JsValue) {
73 Reflect::set(&self.0, &intern(key).into(), value)
74 .expect_throw("cannot write into props object");
75 }
76
77 pub fn insert_callback<T, U>(self, key: &str, f: &Callback<T, U>) -> Self
79 where
80 T: FromWasmAbi + 'static,
81 U: IntoWasmAbi + 'static,
82 {
83 use_tmp_ref(f.clone(), |f| {
84 self.ref_insert(key, &f.as_js());
85 });
86
87 self
88 }
89}
90
91impl AsRef<JsValue> for Props {
92 fn as_ref(&self) -> &JsValue {
93 &self.0
94 }
95}
96
97impl From<Props> for JsValue {
98 fn from(style: Props) -> Self {
99 style.0.into()
100 }
101}
102
103impl From<Object> for Props {
104 fn from(value: Object) -> Self {
105 Props(value)
106 }
107}
108
109impl TryFrom<JsValue> for Props {
110 type Error = JsValue;
111
112 fn try_from(value: JsValue) -> Result<Self, Self::Error> {
113 Ok(Props(value.dyn_into::<Object>()?))
114 }
115}