flams_web_utils/components/
mod.rs

1#![allow(clippy::must_use_candidate)]
2
3mod r#await;
4mod binder;
5mod drawer;
6mod popover;
7mod spinner;
8mod trees;
9
10mod errors;
11pub use errors::*;
12
13#[cfg(any(feature = "ssr", feature = "hydrate"))]
14pub use theming::*;
15mod anchors;
16mod block;
17#[cfg(any(feature = "ssr", feature = "hydrate"))]
18mod theming;
19
20#[cfg(not(any(feature = "ssr", feature = "hydrate")))]
21#[component(transparent)]
22pub fn Themer<Ch: IntoView + 'static>(children: TypedChildren<Ch>) -> impl IntoView {
23    use thaw::ConfigProvider; //,ToasterProvider,Theme};
24    let children = children.into_inner();
25    view! {
26      <ConfigProvider>
27        {children()}
28        //<ToasterProvider>{children()}</ToasterProvider>
29      </ConfigProvider>
30    }
31}
32
33pub use anchors::*;
34pub use block::*;
35pub use drawer::*;
36pub use popover::*;
37pub use r#await::*;
38pub use spinner::*;
39pub use trees::*;
40
41#[leptos::prelude::slot]
42pub struct Header {
43    children: leptos::prelude::Children,
44}
45#[leptos::prelude::slot]
46pub struct Trigger {
47    children: leptos::prelude::Children,
48}
49
50use leptos::prelude::*;
51
52use crate::inject_css;
53
54#[component]
55pub fn Collapsible<Ch: IntoView + 'static>(
56    #[prop(optional)] header: Option<Header>,
57    children: TypedChildren<Ch>,
58    #[prop(optional, into)] expanded: Option<RwSignal<bool>>,
59) -> impl IntoView {
60    let children = children.into_inner();
61    let expanded = expanded.unwrap_or_else(|| RwSignal::new(false));
62    view! {<details open=move || expanded.get()>
63        <summary on:click=move |_| expanded.update(|b| *b = !*b)>{
64            header.map(|c| (c.children)())
65        }</summary>
66        <div>{children()}</div>
67    </details>}
68}
69
70#[component]
71pub fn LazyCollapsible<Ch: IntoView + 'static>(
72    #[prop(optional)] header: Option<Header>,
73    children: TypedChildrenMut<Ch>,
74) -> impl IntoView {
75    let mut children = children.into_inner();
76    let expanded = RwSignal::new(false);
77    view! {<details>
78        <summary on:click=move |_| expanded.update(|b| *b = !*b)>{
79            header.map(|c| (c.children)())
80        }</summary>
81        <div>{move || if expanded.get() {
82          Some(children())
83        } else { None }}</div>
84    </details>}
85}
86
87#[component]
88pub fn Burger<Ch: IntoView + 'static>(children: TypedChildren<Ch>) -> impl IntoView {
89    use icondata_ch::ChMenuHamburger;
90    use thaw::{Menu, MenuPosition, MenuTrigger, MenuTriggerType};
91    inject_css("burger", include_str!("burger.css"));
92    let children = children.into_inner();
93    view! {<ClientOnly><div class="ftml-burger-outer"><div class="ftml-burger">
94      <Menu on_select=|_:String| () trigger_type=MenuTriggerType::Hover position=MenuPosition::Bottom>
95          <MenuTrigger slot><div><thaw::Icon width="2.5em" height="2.5em" icon=ChMenuHamburger/></div></MenuTrigger>
96          {children()}
97      </Menu>
98    </div></div></ClientOnly>}
99}
100
101#[component]
102pub fn ClientOnly<Ch: IntoView + 'static>(children: TypedChildren<Ch>) -> impl IntoView {
103    let children = std::cell::Cell::new(Some(children.into_inner()));
104    let sig = RwSignal::new(false);
105    let rf = NodeRef::new();
106    rf.on_load(move |_| sig.set(true));
107    move || {
108        if sig.get() {
109            leptos::either::Either::Left(children.take().map(|c| c()))
110        } else {
111            leptos::either::Either::Right(view!(<div node_ref = rf/>))
112        }
113    }
114}