Spaces:
Running
Running
File size: 5,173 Bytes
8e04495 |
1 2 3 4 5 6 7 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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
"""Simple snackbar component that is similar to Angular Component Snackbar."""
import time
from typing import Callable, Literal
import mesop as me
@me.stateclass
class State:
is_visible: bool = False
duration: int = 0
horizontal_position: str = "center"
vertical_position: str = "end"
def load(e: me.LoadEvent):
me.set_theme_mode("system")
@me.page(
on_load=load,
security_policy=me.SecurityPolicy(
allowed_iframe_parents=["https://google.github.io", "https://huggingface.co"]
),
path="/snackbar",
)
def app():
me.set_theme_mode("dark")
state = me.state(State)
snackbar(
label="Cannonball!!!",
action_label="Splash",
on_click_action=on_click_snackbar_close,
is_visible=state.is_visible,
horizontal_position=state.horizontal_position, # type: ignore
vertical_position=state.vertical_position, # type: ignore
)
with me.box(style=me.Style(padding=me.Padding.all(30))):
with me.box():
me.select(
label="Horizontal Position",
on_selection_change=on_horizontal_position_change,
options=[
me.SelectOption(label="start", value="start"),
me.SelectOption(label="center", value="center"),
me.SelectOption(label="end", value="end"),
],
)
with me.box():
me.select(
label="Vertical Position",
on_selection_change=on_vertical_position_change,
options=[
me.SelectOption(label="start", value="start"),
me.SelectOption(label="center", value="center"),
me.SelectOption(label="end", value="end"),
],
)
with me.box():
me.select(
label="Duration",
on_selection_change=on_duration_change,
options=[
me.SelectOption(label="None", value="0"),
me.SelectOption(label="3 seconds", value="3"),
],
)
me.button(
"Trigger snackbar",
type="flat",
color="primary",
on_click=on_click_snackbar_open,
)
def on_horizontal_position_change(e: me.SelectSelectionChangeEvent):
state = me.state(State)
state.horizontal_position = e.value
def on_vertical_position_change(e: me.SelectSelectionChangeEvent):
state = me.state(State)
state.vertical_position = e.value
def on_duration_change(e: me.SelectSelectionChangeEvent):
state = me.state(State)
state.duration = int(e.value)
def on_click_snackbar_close(e: me.ClickEvent):
state = me.state(State)
state.is_visible = False
def on_click_snackbar_open(e: me.ClickEvent):
state = me.state(State)
state.is_visible = True
# Use yield to create a timed snackbar message.
if state.duration:
yield
time.sleep(state.duration)
state.is_visible = False
yield
else:
yield
@me.component
def snackbar(
*,
is_visible: bool,
label: str,
action_label: str | None = None,
on_click_action: Callable | None = None,
horizontal_position: Literal["start", "center", "end"] = "center",
vertical_position: Literal["start", "center", "end"] = "end",
):
"""Creates a snackbar.
By default the snackbar is rendered at bottom center.
The on_click_action should typically close the snackbar as part of its actions. If no
click event is included, you'll need to manually hide the snackbar.
Note that there is one issue with this snackbar example. No actions are possible when
using "time.sleep and yield" to imitate a status message that fades away after a
period of time.
Args:
is_visible: Whether the snackbar is currently visible or not.
label: Message for the snackbar
action_label: Optional message for the action of the snackbar
on_click_action: Optional click event when action is triggered.
horizontal_position: Horizontal position of the snackbar
vertical_position: Vertical position of the snackbar
"""
with me.box(
style=me.Style(
display="block" if is_visible else "none",
height="100%",
overflow_x="auto",
overflow_y="auto",
position="fixed",
pointer_events="none",
width="100%",
z_index=1000,
)
):
with me.box(
style=me.Style(
align_items=vertical_position,
height="100%",
display="flex",
justify_content=horizontal_position,
)
):
with me.box(
style=me.Style(
align_items="center",
background=me.theme_var("on-surface-variant"),
border_radius=5,
box_shadow=(
"0 3px 1px -2px #0003, 0 2px 2px #00000024, 0 1px 5px #0000001f"
),
display="flex",
font_size=14,
justify_content="space-between",
margin=me.Margin.all(10),
padding=me.Padding(top=5, bottom=5, right=5, left=15)
if action_label
else me.Padding.all(15),
pointer_events="auto",
width=300,
)
):
me.text(
label, style=me.Style(color=me.theme_var("surface-container-lowest"))
)
if action_label:
me.button(
action_label,
on_click=on_click_action,
style=me.Style(color=me.theme_var("primary-container")),
)
|