Skip to main content

orbital_base_components/form/checkbox/
base.rs

1use leptos::{html, prelude::*};
2
3use crate::form::bind::FormBind;
4use crate::form::field_injection::new_field_id;
5
6/// Headless checkbox — hidden native input, indicator, and optional label.
7#[component(transparent)]
8pub fn BaseCheckbox(
9    #[prop(optional, into)] class: MaybeProp<String>,
10    #[prop(optional, into)] size: MaybeProp<String>,
11    #[prop(optional, into)] checked: FormBind<bool>,
12    #[prop(optional, into)] value: MaybeProp<String>,
13    #[prop(optional, into)] label: MaybeProp<String>,
14    #[prop(optional, into)] name: MaybeProp<String>,
15) -> impl IntoView {
16    let id = new_field_id();
17    let input_ref = NodeRef::<html::Input>::new();
18
19    let checked_bind = checked.clone();
20    let on_change = move |_| {
21        if let Some(input) = input_ref.get_untracked() {
22            checked_bind.set(input.checked());
23        }
24    };
25
26    view! {
27        <span class=move || {
28            let mut parts = Vec::new();
29            if let Some(c) = class.get() {
30                if !c.is_empty() {
31                    parts.push(c);
32                }
33            }
34            if let Some(c) = size.get() {
35                if !c.is_empty() {
36                    parts.push(c);
37                }
38            }
39            parts.join(" ")
40        }>
41            <input
42                type="checkbox"
43                class="sr-only"
44                id=id.clone()
45                name=move || name.get()
46                value=move || value.get()
47                prop:checked=move || checked.get()
48                node_ref=input_ref
49                on:change=on_change
50            />
51            <div aria-hidden="true" role="presentation"></div>
52            {move || {
53                label.get().map(|text| {
54                    view! { <label for=id.clone()>{text}</label> }
55                })
56            }}
57        </span>
58    }
59}