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::*;
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; let children = children.into_inner();
25 view! {
26 <ConfigProvider>
27 {children()}
28 </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}