biji_ui/components/dialog/
dialog.rs1use leptos::{ev::click, prelude::*};
2use leptos_use::use_event_listener;
3
4use crate::{
5 cn, components::dialog::context::DialogContext, custom_animated_show::CustomAnimatedShow,
6};
7
8use super::context::RootContext;
9
10#[component]
11pub fn Trigger(children: Children, #[prop(into, optional)] class: String) -> impl IntoView {
12 let dialog_ctx = expect_context::<DialogContext>();
13
14 let trigger_ref = dialog_ctx.trigger_ref;
15
16 view! {
17 <TriggerEvents>
18 <button node_ref={trigger_ref} class={class}>
19 {children()}
20 </button>
21 </TriggerEvents>
22 }
23}
24
25#[component]
26pub fn TriggerEvents(children: Children) -> impl IntoView {
27 let dialog_ctx = expect_context::<DialogContext>();
28
29 let _ = use_event_listener(dialog_ctx.trigger_ref, click, move |_| {
30 dialog_ctx.toggle();
31 if let Some(trigger_ref) = dialog_ctx.trigger_ref.get() {
32 let _ = trigger_ref.blur();
33 }
34 });
35
36 children()
37}
38
39#[component]
40pub fn Content(
41 children: ChildrenFn,
42 #[prop(into, optional)]
44 class: String,
45 #[prop(into, optional)]
47 show_class: String,
48 #[prop(into, optional)]
50 hide_class: String,
51) -> impl IntoView {
52 let dialog_ctx = expect_context::<DialogContext>();
53
54 view! {
57 <CustomAnimatedShow
58 when={dialog_ctx.open}
59 show_class={cn!(class, show_class)}
60 hide_class={cn!(class, hide_class)}
61 hide_delay={dialog_ctx.hide_delay}
62 >
63 {children()}
64 </CustomAnimatedShow>
65 }
66}
67
68#[component]
69pub fn Overlay(
70 #[prop(into, optional)] class: String,
71 #[prop(into, optional)]
73 show_class: String,
74 #[prop(into, optional)]
76 hide_class: String,
77) -> impl IntoView {
78 let dialog_ctx = expect_context::<DialogContext>();
79 let root_ctx = expect_context::<RootContext>();
80
81 let overlay_ref = root_ctx.overlay_ref;
82
83 view! {
84 <CustomAnimatedShow
85 when={dialog_ctx.open}
86 show_class={cn!(class, show_class)}
87 hide_class={cn!(class, hide_class)}
88 hide_delay={dialog_ctx.hide_delay}
89 >
90 <OverlayEvents>
91 <div node_ref={overlay_ref} style="inset: 0; width: 100%; height: 100%"></div>
92 </OverlayEvents>
93 </CustomAnimatedShow>
94 }
95}
96
97#[component]
98pub fn OverlayEvents(children: Children) -> impl IntoView {
99 let dialog_ctx = expect_context::<DialogContext>();
100 let root_ctx = expect_context::<RootContext>();
101
102 let _ = use_event_listener(root_ctx.overlay_ref, click, move |_| {
103 dialog_ctx.open.set(false);
104 });
105
106 children()
107}
108
109#[component]
110pub fn Close(children: Children, #[prop(into, optional)] class: String) -> impl IntoView {
111 let root_ctx = expect_context::<RootContext>();
112
113 let close_ref = root_ctx.close_ref;
114
115 view! {
116 <CloseEvents>
117 <button node_ref={close_ref} class={class}>
118 {children()}
119 </button>
120 </CloseEvents>
121 }
122}
123
124#[component]
125pub fn CloseEvents(children: Children) -> impl IntoView {
126 let dialog_ctx = expect_context::<DialogContext>();
127 let root_ctx = expect_context::<RootContext>();
128
129 let _ = use_event_listener(root_ctx.close_ref, click, move |_| {
130 dialog_ctx.open.set(false);
131 });
132
133 children()
134}