use crate::components::shared::{CONTROL_MOTION, FOCUS_RING_INSET};
use leptos::prelude::*;
#[component]
pub fn Tabs(
#[prop(into)] value: RwSignal<String>,
#[prop(default = String::new())] class: String,
children: Children,
) -> impl IntoView {
provide_context(value);
let combined = format!("w-full {}", class);
view! {
<div class=combined>{children()}</div>
}
}
#[component]
pub fn TabsList(
#[prop(default = String::new())] class: String,
children: Children,
) -> impl IntoView {
let combined = format!(
"inline-flex h-9 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground {}",
class
);
view! {
<div role="tablist" class=combined>{children()}</div>
}
}
#[component]
pub fn TabsTrigger(
#[prop(into)] value: String,
#[prop(default = String::new())] class: String,
children: Children,
) -> impl IntoView {
let active = use_context::<RwSignal<String>>().expect("TabsTrigger must be used inside Tabs");
let val = StoredValue::new(value);
view! {
<button
role="tab"
class=move || {
let base = format!("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1 text-sm font-medium {} {}", FOCUS_RING_INSET, CONTROL_MOTION);
let active_cls = "bg-background text-foreground shadow-elev-sm";
let inactive_cls = "hover:bg-muted/50 hover:text-foreground";
let extra = if class.is_empty() { "" } else { &class };
if active.get() == val.get_value() {
format!("{} {} {}", base, active_cls, extra)
} else {
format!("{} {} {}", base, inactive_cls, extra)
}
}
aria-selected=move || if active.get() == val.get_value() { "true" } else { "false" }
on:click=move |_| active.set(val.get_value())
>
{children()}
</button>
}
}
#[component]
pub fn TabsContent(
#[prop(into)] value: String,
#[prop(default = String::new())] class: String,
children: ChildrenFn,
) -> impl IntoView {
let active = use_context::<RwSignal<String>>().expect("TabsContent must be used inside Tabs");
let val = StoredValue::new(value);
let combined = format!("mt-2 focus:outline-none {}", class);
view! {
<Show when=move || active.get() == val.get_value()>
<div role="tabpanel" class=combined.clone()>
{children()}
</div>
</Show>
}
}