radix_leptos_toggle/
toggle.rs1use leptos::{ev::MouseEvent, html::AnyElement, *};
2use radix_leptos_primitive::{compose_callbacks, Primitive};
3use radix_leptos_use_controllable_state::{use_controllable_state, UseControllableStateParams};
4
5#[component]
6pub fn Toggle(
7 #[prop(into, optional)]
9 pressed: MaybeProp<bool>,
10 #[prop(into, optional)]
12 default_pressed: MaybeProp<bool>,
13 #[prop(into, optional)]
15 on_pressed_change: Option<Callback<bool>>,
16 #[prop(into, optional)] disabled: MaybeProp<bool>,
17 #[prop(into, optional)] on_click: Option<Callback<MouseEvent>>,
18 #[prop(into, optional)] as_child: MaybeProp<bool>,
19 #[prop(optional)] node_ref: NodeRef<AnyElement>,
20 #[prop(attrs)] attrs: Vec<(&'static str, Attribute)>,
21 children: ChildrenFn,
22) -> impl IntoView {
23 let disabled = Signal::derive(move || disabled.get().unwrap_or(false));
24
25 let (pressed, set_pressed) = use_controllable_state(UseControllableStateParams {
26 prop: pressed,
27 on_change: on_pressed_change.map(|on_pressed_change| {
28 Callback::new(move |value| {
29 if let Some(value) = value {
30 on_pressed_change.call(value);
31 }
32 })
33 }),
34 default_prop: default_pressed,
35 });
36 let pressed = Signal::derive(move || pressed.get().unwrap_or(false));
37
38 let mut attrs = attrs.clone();
39 attrs.extend([
40 ("aria-pressed", pressed.into_attribute()),
41 (
42 "data-state",
43 (move || match pressed.get() {
44 true => "on",
45 false => "off",
46 })
47 .into_attribute(),
48 ),
49 (
50 "data-disabled",
51 (move || disabled.get().then_some("")).into_attribute(),
52 ),
53 (
54 "disabled",
55 (move || disabled.get().then_some("")).into_attribute(),
56 ),
57 ]);
58
59 view! {
60 <Primitive
61 element=html::button
62 as_child=as_child
63 node_ref=node_ref
64 attrs=attrs
65 on:click=compose_callbacks(on_click, Some(Callback::new(move |_| {
66 if !disabled.get() {
67 set_pressed.call(Some(!pressed.get()));
68 }
69 })), None)
70 >
71 {children()}
72 </Primitive>
73 }
74}