Open Zagitta opened 4 months ago
This is a really needed feature. Is it considered as part of the upcoming ver. 0.6, please?
Here is a fixed example from here:
#[derive(Props, PartialEq, Clone)]
struct ButtonProps {
#[props(extends = GlobalAttributes)]
attributes: Vec<Attribute>,
onclick: Option<EventHandler<MouseEvent>>,
}
#[component]
fn ResetButton(props: ButtonProps) -> Element {
rsx! {
button {
class: "reset",
onclick: move |event| if let Some(f) = props.onclick.as_ref() { f(event) }
..props.attributes,
img { src: RESET_ICON }
}
}
}
You would have to do this manually for every callback/"on*" attribute. I doubt this will be included in the 0.6.
@Andrew15-5 Thanks, Andrew! That's great for event handlers.
And maybe I'm missing something, but this looks pretty similar with the example - that FancyButton
- from official Event Handlers page, except that in this case an Option
of EventHandler<MouseEvent>
is used.
And revisiting that page, I realised that there is a simple way to pass a closure that needs to call an async fn
.
Here is a recent example:
#[derive(Props, PartialEq, Clone)]
pub struct ConfirmDeleteModalProps {
pub title: String,
pub content: String,
pub action: Signal<Action>,
pub show_delete_confirm: Signal<bool>,
pub delete_handler: EventHandler,
}
#[component]
pub fn ConfirmDeleteModal(props: ConfirmDeleteModalProps) -> Element {
let ConfirmDeleteModalProps {
title,
content,
mut action,
mut show_delete_confirm,
delete_handler,
} = props;
rsx! {
div { class: "fixed inset-0 p-4 flex flex-wrap justify-center items-center w-full h-full z-[1000] before:fixed before:inset-0 before:w-full before:h-full before:bg-[rgba(0,0,0,0.5)] overflow-auto font-[sans-serif]",
div { class: "w-full max-w-lg bg-white shadow-lg rounded-lg p-8 relative",
div {
h4 { class: "text-sm text-gray-800 font-semibold", {title} }
p { class: "text-sm text-gray-600 mt-4", { content } }
}
div { class: "flex justify-between mt-8",
button {
class: "text-red-600 bg-red-50 hover:text-red-800 hover:bg-red-100 drop-shadow-sm px-4 rounded-md",
onclick: move |_| {
show_delete_confirm.set(false);
action.set(Action::Delete);
delete_handler(());
},
"Delete"
}
button {
class: "bg-gray-100 bg-green-100 enabled:hover:bg-green-100 disabled:text-gray-400 hover:disabled:bg-gray-100 drop-shadow-sm px-4 rounded-md",
onclick: move |_| {
show_delete_confirm.set(false);
},
"Cancel"
}
}
}
}
}
}
And that reusable component being used as such:
#[derive(PartialEq, Props, Clone)]
pub struct AttributeDefEditPageProps {
attr_def_id: Id,
}
#[component]
pub fn AttributeDefPage(props: AttributeDefEditPageProps) -> Element {
//
let mut action = use_signal(|| Action::View);
let mut show_delete_confirm = use_signal(|| false);
rsx! {
div { class: "flex flex-col min-h-screen bg-gray-100",
...
if show_delete_confirm() {
ConfirmDeleteModal {
title: "Confirm Delete",
content: "Are you sure you want to delete this attribute definition?",
action,
show_delete_confirm,
delete_handler: move |_| {
spawn(async move {
log::debug!("Calling handle_delete ...");
handle_delete(&id(), action_done, err).await;
});
}
}
}
}
}
}
async fn handle_delete(id: &Id, mut saved: Signal<bool>, mut err: Signal<Option<String>>) {
//
log::debug!(">>> Deleting attribute definition: {:?}", id);
match remove_attr_def(id.clone()).await {
Ok(_) => {
saved.set(true);
err.set(None);
}
Err(e) => {
saved.set(false);
err.set(Some(e.to_string()));
}
}
}
Feature Request
It would be nice to be able to create wrapper components that also can pass down callbacks. For example, I'm creating a small select wrapper with some tailwind styling and a label:
Which I then would like to use like this:
However that that gives the following unexpected error:
Ideally, this should just work and pass down the callback as expected without requiring anything from the user.