impulse_thaw/message_bar/
message_bar.rs1use leptos::{context::Provider, either::EitherOf4, prelude::*};
2use thaw_utils::{class_list, mount_style};
3
4#[component]
9pub fn MessageBar(
10 #[prop(optional, into)] class: MaybeProp<String>,
11 #[prop(optional, into)] layout: MessageBarLayout,
12 #[prop(optional, into)]
14 intent: Signal<MessageBarIntent>,
15 children: Children,
16) -> impl IntoView {
17 mount_style("message-bar", include_str!("./message-bar.css"));
18
19 view! {
20 <div
21 class=class_list![
22 "thaw-message-bar",
23 move || format!("thaw-message-bar--{}", intent.get().as_str()),
24 move || format!("thaw-message-bar--{}", layout.as_str()),
25 class
26 ]
27 role="group"
28 >
29 <div class="thaw-message-bar__icon">
30 {move || match intent.get() {
31 MessageBarIntent::Info => {
32 EitherOf4::A(
33 view! {
34 <svg
35 fill="currentColor"
36 aria-hidden="true"
37 width="1em"
38 height="1em"
39 viewBox="0 0 20 20"
40 >
41 <path
42 d="M18 10a8 8 0 1 0-16 0 8 8 0 0 0 16 0ZM9.5 8.91a.5.5 0 0 1 1 0V13.6a.5.5 0 0 1-1 0V8.9Zm-.25-2.16a.75.75 0 1 1 1.5 0 .75.75 0 0 1-1.5 0Z"
43 fill="currentColor"
44 ></path>
45 </svg>
46 },
47 )
48 }
49 MessageBarIntent::Success => {
50 EitherOf4::B(
51 view! {
52 <svg
53 fill="currentColor"
54 aria-hidden="true"
55 width="1em"
56 height="1em"
57 viewBox="0 0 20 20"
58 >
59 <path
60 d="M10 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16Zm3.36 5.65a.5.5 0 0 0-.64-.06l-.07.06L9 11.3 7.35 9.65l-.07-.06a.5.5 0 0 0-.7.7l.07.07 2 2 .07.06c.17.11.4.11.56 0l.07-.06 4-4 .07-.08a.5.5 0 0 0-.06-.63Z"
61 fill="currentColor"
62 ></path>
63 </svg>
64 },
65 )
66 }
67 MessageBarIntent::Warning => {
68 EitherOf4::C(
69 view! {
70 <svg
71 fill="currentColor"
72 aria-hidden="true"
73 width="1em"
74 height="1em"
75 viewBox="0 0 20 20"
76 >
77 <path
78 d="M8.68 2.79a1.5 1.5 0 0 1 2.64 0l6.5 12A1.5 1.5 0 0 1 16.5 17h-13a1.5 1.5 0 0 1-1.32-2.21l6.5-12ZM10.5 7.5a.5.5 0 0 0-1 0v4a.5.5 0 0 0 1 0v-4Zm.25 6.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"
79 fill="currentColor"
80 ></path>
81 </svg>
82 },
83 )
84 }
85 MessageBarIntent::Error => {
86 EitherOf4::D(
87 view! {
88 <svg
89 fill="currentColor"
90 aria-hidden="true"
91 width="1em"
92 height="1em"
93 viewBox="0 0 20 20"
94 >
95 <path
96 d="M10 2a8 8 0 1 1 0 16 8 8 0 0 1 0-16ZM7.8 7.11a.5.5 0 0 0-.63.06l-.06.07a.5.5 0 0 0 .06.64L9.3 10l-2.12 2.12-.06.07a.5.5 0 0 0 .06.64l.07.06c.2.13.47.11.64-.06L10 10.7l2.12 2.12.07.06c.2.13.46.11.64-.06l.06-.07a.5.5 0 0 0-.06-.64L10.7 10l2.12-2.12.06-.07a.5.5 0 0 0-.06-.64l-.07-.06a.5.5 0 0 0-.64.06L10 9.3 7.88 7.17l-.07-.06Z"
97 fill="currentColor"
98 ></path>
99 </svg>
100 },
101 )
102 }
103 }}
104
105 </div>
106 <Provider value=MessageBarInjection { layout }>{children()}</Provider>
107 </div>
108 }
109}
110
111#[derive(Debug, Clone)]
112pub(crate) struct MessageBarInjection {
113 pub layout: MessageBarLayout,
114}
115
116impl MessageBarInjection {
117 pub fn expect_context() -> Self {
118 expect_context()
119 }
120}
121
122#[derive(Default, Clone)]
123pub enum MessageBarIntent {
124 #[default]
125 Info,
126 Success,
127 Warning,
128 Error,
129}
130
131impl MessageBarIntent {
132 pub fn as_str(&self) -> &'static str {
133 match self {
134 MessageBarIntent::Info => "into",
135 MessageBarIntent::Success => "success",
136 MessageBarIntent::Warning => "warning",
137 MessageBarIntent::Error => "error",
138 }
139 }
140}
141
142#[derive(Debug, Default, Clone, Copy, PartialEq)]
143pub enum MessageBarLayout {
144 #[default]
145 Singleline,
146 Multiline,
147}
148
149impl MessageBarLayout {
150 pub fn as_str(&self) -> &'static str {
151 match self {
152 MessageBarLayout::Singleline => "singleline",
153 MessageBarLayout::Multiline => "multiline",
154 }
155 }
156}