flams_web_utils/components/
mod.rs1#![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::*;
12use ftml_dom::utils::css::inject_css;
13use leptos::prelude::*;
14
15mod anchors;
18mod block;
19pub use anchors::*;
38pub use block::*;
39pub use drawer::*;
40pub use popover::*;
41pub use r#await::*;
42pub use spinner::*;
43pub use trees::*;
44
45#[leptos::prelude::slot]
46pub struct Header {
47 children: leptos::prelude::Children,
48}
49#[leptos::prelude::slot]
50pub struct Trigger {
51 children: leptos::prelude::Children,
52}
53
54#[component]
55pub fn Collapsible(
56 #[prop(optional)] header: Option<Header>,
57 children: Children,
58 #[prop(optional, into)] expanded: Option<RwSignal<bool>>,
59) -> impl IntoView {
60 let expanded = expanded.unwrap_or_else(|| RwSignal::new(false));
61 view! {<details open=move || expanded.get()>
62 <summary on:click=move |_| expanded.update(|b| *b = !*b)>{
63 header.map(|c| (c.children)())
64 }</summary>
65 <div>{children()}</div>
66 </details>}
67}
68
69#[component]
70pub fn LazyCollapsible(
71 #[prop(optional)] header: Option<Header>,
72 mut children: ChildrenFnMut,
73) -> impl IntoView {
74 let expanded = RwSignal::new(false);
75 view! {<details>
76 <summary on:click=move |_| expanded.update(|b| *b = !*b)>{
77 header.map(|c| (c.children)())
78 }</summary>
79 <div>{move || if expanded.get() {
80 Some(children())
81 } else { None }}</div>
82 </details>}
83}
84
85#[component]
86pub fn Burger(children: Children) -> impl IntoView {
87 use icondata_ch::ChMenuHamburger;
88 use thaw::{Menu, MenuPosition, MenuTrigger, MenuTriggerType};
89 inject_css("burger", include_str!("burger.css"));
90 view! {<ClientOnly><div class="ftml-burger-outer"><div class="ftml-burger">
91 <Menu on_select=|_:String| () trigger_type=MenuTriggerType::Hover position=MenuPosition::Bottom>
92 <MenuTrigger slot><div><thaw::Icon width="2.5em" height="2.5em" icon=ChMenuHamburger/></div></MenuTrigger>
93 {children()}
94 </Menu>
95 </div></div></ClientOnly>}
96}
97
98#[component]
99pub fn ClientOnly(children: Children) -> impl IntoView {
100 let children = std::cell::Cell::new(Some(children));
101 let sig = RwSignal::new(false);
102 let rf = NodeRef::new();
103 rf.on_load(move |_| sig.set(true));
104 move || {
105 if sig.get() {
106 leptos::either::Either::Left(children.take().map(|c| c()))
107 } else {
108 leptos::either::Either::Right(view!(<div node_ref = rf/>))
109 }
110 }
111}