8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 | @sl.component
def Dialog(
open: Union[sl.Reactive[bool], bool],
*,
on_close: Union[None, Callable[[], None]] = None,
content: Union[str, sl.Element] = "",
title: str = "Confirm action",
ok: Union[Optional[str], sl.Element] = "OK",
on_ok: Callable[[], None] = lambda: None,
ok_enable: Union[sl.Reactive[bool], bool] = True,
close_on_ok: bool = True,
cancel: Union[str, sl.Element] = "Cancel",
on_cancel: Callable[[], None] = lambda: None,
children: List[sl.Element] = [],
max_width: Union[int, str] = 500,
persistent: bool = False,
):
"""Custom dialog component"""
def on_open(open_value):
if not open_value:
if on_close:
on_close()
open_reactive = sl.use_reactive(open, on_open)
ok_reactive = sl.use_reactive(ok_enable)
del open
del ok_enable
def close():
open_reactive.set(False)
user_on_click_ok = None
user_on_click_cancel = None
def perform_ok():
if user_on_click_ok:
user_on_click_ok()
on_ok()
if close_on_ok:
close()
def perform_cancel():
if user_on_click_cancel:
user_on_click_cancel()
on_cancel()
close()
def on_v_model(value):
if not value:
on_cancel()
open_reactive.set(value)
with v.Dialog(
v_model=open_reactive.value,
on_v_model=on_v_model,
persistent=persistent,
max_width=max_width,
):
with sl.v.Card():
sl.v.CardTitle(children=[title])
with sl.v.CardText(style_="min-height: 64px"):
if isinstance(content, str):
sl.Text(content)
else:
sl.display(content)
if children:
sl.display(*children)
with sl.v.CardActions(class_="justify-end"):
if isinstance(cancel, str):
sl.Button(
label=cancel,
on_click=perform_cancel,
text=True,
classes=["grey--text", "text--darken-2"],
)
else:
# the user may have passed in on_click already
user_on_click_cancel = cancel.kwargs.get("on_click")
# override or add our own on_click handler
cancel.kwargs = {
**cancel.kwargs, "on_click": perform_cancel
}
sl.display(cancel)
# similar as cancel
if isinstance(ok, str):
sl.Button(
label=ok,
on_click=perform_ok,
dark=True,
color="primary",
disabled=not ok_reactive.value,
elevation=0,
)
elif ok is None:
# no ok button
pass
else:
user_on_click_ok = ok.kwargs.get("on_click")
ok.kwargs = {**ok.kwargs, "on_click": perform_ok}
sl.display(ok)
|