use crate::AccordionInjection;
use leptos::prelude::*;
use thaw_components::CSSTransition;
use thaw_utils::{class_list, mount_style, update, with};
#[component]
pub fn AccordionItem(
#[prop(optional, into)] class: MaybeProp<String>,
#[prop(into)]
value: Signal<String>,
accordion_header: AccordionHeader,
children: Children,
) -> impl IntoView {
mount_style("accordion-item", include_str!("./accordion-item.css"));
let AccordionInjection {
open_items,
multiple,
collapsible,
} = AccordionInjection::expect_context();
let is_show_panel = Memo::new(move |_| with!(|open_items, value| open_items.contains(value)));
let on_click = move |_| {
let is_show_panel = is_show_panel.get_untracked();
update!(move |open_items| {
if is_show_panel {
if collapsible {
with!(|value| open_items.remove(value));
} else if multiple {
with!(|value| open_items.remove(value));
}
} else {
if !multiple {
open_items.clear();
}
open_items.insert(value.get_untracked());
}
});
};
view! {
<div class=class_list!["thaw-accordion-item", class]>
<div class="thaw-accordion-header">
<button
class="thaw-accordion-header__button"
aria-expanded=move || is_show_panel.get().to_string()
type="button"
on:click=on_click
>
<span class="thaw-accordion-header__expand-icon" aria-hidden="true">
<svg
fill="currentColor"
aria-hidden="true"
width="1em"
height="1em"
viewBox="0 0 20 20"
style=move || {
if is_show_panel.get() {
"transform: rotate(90deg)"
} else {
"transform: rotate(0deg)"
}
}
>
<path
d="M7.65 4.15c.2-.2.5-.2.7 0l5.49 5.46c.21.22.21.57 0 .78l-5.49 5.46a.5.5 0 0 1-.7-.7L12.8 10 7.65 4.85a.5.5 0 0 1 0-.7Z"
fill="currentColor"
></path>
</svg>
</span>
{(accordion_header.children)()}
</button>
</div>
<CSSTransition show=is_show_panel name="thaw-accordion-panel">
<div class="thaw-accordion-panel">
{children()}
</div>
</CSSTransition>
</div>
}
}
#[slot]
pub struct AccordionHeader {
children: Children,
}