-
Notifications
You must be signed in to change notification settings - Fork 144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add value_container for provide on_update to checkbox #287
Conversation
This looks good to me |
let default_checked = checked(); | ||
|
||
let checked_signal = create_rw_signal(default_checked); | ||
create_effect(move |_| { | ||
let checked = checked(); | ||
checked_signal.set(checked); | ||
}); | ||
|
||
let update_checked_signal = create_rw_signal(default_checked); | ||
create_effect(move |_| { | ||
let checked = update_checked_signal.get(); | ||
checked_signal.set(checked); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if there's a way to simplify this part. Since any composited widget that returns a ValueContainer will follow the pattern set up here, any simplification will pay off for Floem devs as well as users who make their own components.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is probably quite different for different views I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I get back from work tonight, I'd like to try rewriting this widget so it doesn't require additional signals and effects. I might arrive at the same conclusion, but it would be satisfying to achieve a simpler result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like I reduced the amount of additional signals from two to one and preserved the original ReadSignal parameter without breaking anything:
test.mp4
/// Renders a checkbox using the provided checked signal.
pub fn labeled_checkbox<S: Display + 'static>(
checked: ReadSignal<bool>,
label: impl Fn() -> S + 'static,
) -> ValueContainer<bool> {
let inner_signal = create_rw_signal(checked.get_untracked());
create_effect(move |_| {
if checked.get() != inner_signal.get_untracked() {
inner_signal.set(checked.get());
}
});
value_container(
h_stack((checkbox_svg(inner_signal.read_only()), views::label(label)))
.class(LabeledCheckboxClass)
.style(|s| s.items_center().justify_center()),
move || inner_signal.get(),
)
.keyboard_navigatable()
.on_click_stop(move |_| {
inner_signal.set(!checked.get());
})
}
If this aligns with your intentions, I might be able to further simplify the implementation - specifically the part about the inner signal that propagates changes from the input events to the on_update
. It might be possible to create a helper function for this to minimize repetitive code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a new iteration that builds on your work: #289
/// Renders a checkbox using the provided checked signal.
pub fn labeled_checkbox<S: Display + 'static>(
checked: ReadSignal<bool>,
label: impl Fn() -> S + 'static,
) -> ValueContainer<bool> {
let (inner_signal, set_inner_signal) = create_inner_signal(checked);
value_container(
h_stack((checkbox_svg(inner_signal), views::label(label)))
.class(LabeledCheckboxClass)
.style(|s| s.items_center().justify_center())
.keyboard_navigatable()
.on_click_stop(move |_| {
set_inner_signal.set(!checked.get());
}),
inner_signal,
)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That part I understand, but in what situation would someone need a closure instead of a ReadSignal? As far as I'm aware,
checkbox(|| false)
is a checkbox that can never be checked. So I'm not sure I understand the use case.
When you click it, it will trigger on_update
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That part I understand, but in what situation would someone need a closure instead of a ReadSignal? As far as I'm aware,
checkbox(|| false)
is a checkbox that can never be checked. So I'm not sure I understand the use case.
That closure will only be run once since it doesn't contain a signal. So it will only set the initial state. If it contained a signal then it would set it every time that the signal changed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That part I understand, but in what situation would someone need a closure instead of a ReadSignal?
One use case that I can think of is for some kind of derived signal -- a simple closure that computes a value using other "real" signals:
let count = create_rw_signal(0);
checkbox(|| count.get() == 42)
.on_update(|checked| count.set(42));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One use case that I can think of is for some kind of derived signal -- a simple closure that computes a value using other "real" signals:
let count = create_rw_signal(0); checkbox(|| count.get() == 42) .on_update(|checked| count.set(42));
I run into this all the time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks everyone for explaining. Now that I understand the purpose, I made the necessary modifications to support checkbox(|| false)
at #290 and created a generic function create_value_container_signals
with documentation to make it reusable. I hope it's useful.
pub fn checkbox(checked: ReadSignal<bool>) -> impl View { | ||
checkbox_svg(checked).keyboard_navigatable() | ||
pub fn checkbox(checked: impl Fn() -> bool + 'static) -> ValueContainer<bool> { | ||
labeled_checkbox(checked, || "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
close in favour of #290 |
No description provided.