mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
feat: adds MessageBar component
This commit is contained in:
parent
b992a3eda7
commit
348cc76c80
21 changed files with 374 additions and 224 deletions
|
@ -47,7 +47,6 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
|
|||
// <Route path="/nav-bar" view=NavBarPage/>
|
||||
// <Route path="/toast" view=ToastPage/>
|
||||
<Route path="/accordion" view=AccordionMdPage/>
|
||||
<Route path="/alert" view=AlertMdPage/>
|
||||
<Route path="/anchor" view=AnchorMdPage/>
|
||||
<Route path="/auto-complete" view=AutoCompleteMdPage/>
|
||||
<Route path="/avatar" view=AvatarMdPage/>
|
||||
|
@ -70,7 +69,8 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
|
|||
<Route path="/input" view=InputMdPage/>
|
||||
<Route path="/layout" view=LayoutMdPage/>
|
||||
<Route path="/loading-bar" view=LoadingBarMdPage/>
|
||||
<Route path="/message" view=MessageMdPage/>
|
||||
// <Route path="/message" view=MessageMdPage/>
|
||||
<Route path="/message-bar" view=MessageBarMdPage/>
|
||||
<Route path="/modal" view=ModalMdPage/>
|
||||
<Route path="/popover" view=PopoverMdPage/>
|
||||
<Route path="/progress" view=ProgressMdPage/>
|
||||
|
@ -118,9 +118,9 @@ fn TheProvider(children: Children) -> impl IntoView {
|
|||
view! {
|
||||
<ConfigProvider theme>
|
||||
<ThemeProvider theme>
|
||||
<MessageProvider>
|
||||
// <MessageProvider>
|
||||
<LoadingBarProvider>{children()}</LoadingBarProvider>
|
||||
</MessageProvider>
|
||||
// </MessageProvider>
|
||||
</ThemeProvider>
|
||||
</ConfigProvider>
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@ use thaw::*;
|
|||
#[component]
|
||||
pub fn SwitchVersion() -> impl IntoView {
|
||||
let options = vec![
|
||||
SelectOption::new("main", "https://thawui.vercel.app".into()),
|
||||
SelectOption::new("0.3.0", "https://thaw-gxcwse9r5-thaw.vercel.app".into()),
|
||||
SelectOption::new("0.2.6", "https://thaw-mzh1656cm-thaw.vercel.app".into()),
|
||||
SelectOption::new("0.2.5", "https://thaw-8og1kv8zs-thaw.vercel.app".into()),
|
||||
("main", "https://thawui.vercel.app"),
|
||||
("0.3.0", "https://thaw-gxcwse9r5-thaw.vercel.app"),
|
||||
("0.2.6", "https://thaw-mzh1656cm-thaw.vercel.app"),
|
||||
("0.2.5", "https://thaw-8og1kv8zs-thaw.vercel.app"),
|
||||
];
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
|
@ -28,6 +28,14 @@ pub fn SwitchVersion() -> impl IntoView {
|
|||
}
|
||||
|
||||
view! {
|
||||
<Select value=version options/>
|
||||
<Combobox>
|
||||
{
|
||||
options.into_iter().map(|option| view! {
|
||||
<ComboboxOption key=option.1>
|
||||
{option.0}
|
||||
</ComboboxOption>
|
||||
}).collect_view()
|
||||
}
|
||||
</Combobox>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,10 +139,6 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
|||
value: "/components/accordion".into(),
|
||||
label: "Accordion".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/alert".into(),
|
||||
label: "Alert".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/anchor".into(),
|
||||
label: "Anchor".into(),
|
||||
|
@ -231,9 +227,13 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
|||
value: "/components/loading-bar".into(),
|
||||
label: "Loading Bar".into(),
|
||||
},
|
||||
// MenuItemOption {
|
||||
// value: "/components/message".into(),
|
||||
// label: "Message".into(),
|
||||
// },
|
||||
MenuItemOption {
|
||||
value: "/components/message".into(),
|
||||
label: "Message".into(),
|
||||
value: "/components/message-bar".into(),
|
||||
label: "Message Bar".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/modal".into(),
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
# Alert
|
||||
|
||||
```rust demo
|
||||
view! {
|
||||
<Space vertical=true>
|
||||
<Alert variant=AlertVariant::Success title="title">
|
||||
"success"
|
||||
</Alert>
|
||||
<Alert variant=AlertVariant::Warning title="title">
|
||||
"warning"
|
||||
</Alert>
|
||||
<Alert variant=AlertVariant::Error title="title">
|
||||
"error"
|
||||
</Alert>
|
||||
</Space>
|
||||
}
|
||||
```
|
||||
|
||||
### Alert Props
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| -------- | ----------------------------------- | -------------------- | ----------------------------------------- |
|
||||
| class | `OptionalProp<MaybeSignal<String>>` | `Default::default()` | Additional classes for the alert element. |
|
||||
| title | `Option<MaybeSignal<String>>` | `Default::default()` | Title of the alert. |
|
||||
| variant | `MaybeSignal<AlertVariant>` | | Alert variant. |
|
||||
| children | `Children` | | The content of the alert. |
|
|
@ -1,8 +1,13 @@
|
|||
# Loading Bar
|
||||
|
||||
<Alert variant=AlertVariant::Warning title="Prerequisite">
|
||||
<MessageBar layout=MessageBarLayout::Multiline intent=MessageBarIntent::Warning>
|
||||
<MessageBarBody>
|
||||
<h3 style="margin: 0">"Prerequisite"</h3>
|
||||
<p>
|
||||
"If you want to use loading bar, you need to wrap the component where you call related methods inside LoadingBarProvider and use use_loading_bar to get the API."
|
||||
</Alert>
|
||||
</p>
|
||||
</MessageBarBody>
|
||||
</MessageBar>
|
||||
|
||||
```rust demo
|
||||
let loading_bar = use_loading_bar();
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
# Message
|
||||
|
||||
<Alert variant=AlertVariant::Warning title="Prerequisite">
|
||||
<MessageBar layout=MessageBarLayout::Multiline intent=MessageBarIntent::Warning>
|
||||
<MessageBarBody>
|
||||
<h3 style="margin: 0">"Prerequisite"</h3>
|
||||
<p>
|
||||
"If you want to use message, you need to wrap the component where you call related methods inside MessageProvider and use use_message to get the API."
|
||||
</Alert>
|
||||
</p>
|
||||
</MessageBarBody>
|
||||
</MessageBar>
|
||||
|
||||
```rust demo
|
||||
let message = use_message();
|
||||
|
|
67
demo_markdown/docs/message_bar/mod.md
Normal file
67
demo_markdown/docs/message_bar/mod.md
Normal file
|
@ -0,0 +1,67 @@
|
|||
# MessageBar
|
||||
|
||||
```rust demo
|
||||
view! {
|
||||
<MessageBar>
|
||||
<MessageBarBody>
|
||||
<MessageBarTitle>Descriptive title</MessageBarTitle>
|
||||
"Message providing information to the user with actionable insights."
|
||||
</MessageBarBody>
|
||||
<MessageBarActions>
|
||||
<Button size=ButtonSize::Small>"Action"</Button>
|
||||
<Button size=ButtonSize::Small>"Action"</Button>
|
||||
<MessageBarContainerAction slot>
|
||||
<Button size=ButtonSize::Small appearance=ButtonAppearance::Transparent>
|
||||
"X"
|
||||
</Button>
|
||||
</MessageBarContainerAction>
|
||||
</MessageBarActions>
|
||||
</MessageBar>
|
||||
}
|
||||
```
|
||||
|
||||
### Intent
|
||||
|
||||
```rust demo
|
||||
view! {
|
||||
<Space vertical=true>
|
||||
<MessageBar>
|
||||
<MessageBarBody>
|
||||
<MessageBarTitle>"Intent info"</MessageBarTitle>
|
||||
"Message providing information to the user with actionable insights."
|
||||
</MessageBarBody>
|
||||
</MessageBar>
|
||||
<MessageBar intent=MessageBarIntent::Warning>
|
||||
<MessageBarBody>
|
||||
<MessageBarTitle>"Intent warning"</MessageBarTitle>
|
||||
"Message providing information to the user with actionable insights."
|
||||
</MessageBarBody>
|
||||
</MessageBar>
|
||||
<MessageBar intent=MessageBarIntent::Error>
|
||||
<MessageBarBody>
|
||||
<MessageBarTitle>"Intent error"</MessageBarTitle>
|
||||
"Message providing information to the user with actionable insights."
|
||||
</MessageBarBody>
|
||||
</MessageBar>
|
||||
<MessageBar intent=MessageBarIntent::Success>
|
||||
<MessageBarBody>
|
||||
<MessageBarTitle>"Intent success"</MessageBarTitle>
|
||||
"Message providing information to the user with actionable insights."
|
||||
</MessageBarBody>
|
||||
</MessageBar>
|
||||
</Space>
|
||||
}
|
||||
```
|
||||
|
||||
### Manual Layout
|
||||
|
||||
```rust demo
|
||||
view! {
|
||||
<MessageBar layout=MessageBarLayout::Multiline>
|
||||
<MessageBarBody>
|
||||
<h3 style="margin: 0">"Descriptive title"</h3>
|
||||
<p>"Message providing information to the user with actionable insights."</p>
|
||||
</MessageBarBody>
|
||||
</MessageBar>
|
||||
}
|
||||
```
|
|
@ -29,7 +29,7 @@ pub fn include_md(_token_stream: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
// "TabbarMdPage" => "../docs/_mobile/tabbar/mod.md",
|
||||
// "ToastMdPage" => "../docs/_mobile/toast/mod.md",
|
||||
"AccordionMdPage" => "../docs/accordion/mod.md",
|
||||
"AlertMdPage" => "../docs/alert/mod.md",
|
||||
// "AlertMdPage" => "../docs/alert/mod.md",
|
||||
"AnchorMdPage" => "../docs/anchor/mod.md",
|
||||
"AutoCompleteMdPage" => "../docs/auto_complete/mod.md",
|
||||
"AvatarMdPage" => "../docs/avatar/mod.md",
|
||||
|
@ -52,7 +52,8 @@ pub fn include_md(_token_stream: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
"InputMdPage" => "../docs/input/mod.md",
|
||||
"LayoutMdPage" => "../docs/layout/mod.md",
|
||||
"LoadingBarMdPage" => "../docs/loading_bar/mod.md",
|
||||
"MessageMdPage" => "../docs/message/mod.md",
|
||||
// "MessageMdPage" => "../docs/message/mod.md",
|
||||
"MessageBarMdPage" => "../docs/message_bar/mod.md",
|
||||
"ModalMdPage" => "../docs/modal/mod.md",
|
||||
"PopoverMdPage" => "../docs/popover/mod.md",
|
||||
"ProgressMdPage" => "../docs/progress/mod.md",
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
.thaw-alert {
|
||||
position: relative;
|
||||
padding: 14px 20px 14px 42px;
|
||||
background-color: var(--thaw-background-color);
|
||||
border: 1px solid var(--thaw-border-color);
|
||||
border-radius: 3px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.thaw-alert__icon {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 10px;
|
||||
font-size: 24px;
|
||||
color: var(--thaw-icon-color);
|
||||
}
|
||||
|
||||
.thaw-alert__header {
|
||||
font-size: 16px;
|
||||
line-height: 19px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.thaw-alert__header + .thaw-alert__content {
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
mod theme;
|
||||
|
||||
pub use theme::AlertTheme;
|
||||
|
||||
use crate::{theme::use_theme, Icon, Theme};
|
||||
use leptos::*;
|
||||
use thaw_components::OptionComp;
|
||||
use thaw_utils::{class_list, mount_style, OptionalProp};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum AlertVariant {
|
||||
Success,
|
||||
Warning,
|
||||
Error,
|
||||
}
|
||||
|
||||
impl AlertVariant {
|
||||
fn theme_icon_color(&self, theme: &Theme) -> String {
|
||||
match self {
|
||||
AlertVariant::Success => theme.common.color_success.clone(),
|
||||
AlertVariant::Warning => theme.common.color_warning.clone(),
|
||||
AlertVariant::Error => theme.common.color_error.clone(),
|
||||
}
|
||||
}
|
||||
fn theme_background_color(&self, theme: &Theme) -> String {
|
||||
match self {
|
||||
AlertVariant::Success => theme.alert.success_background_color.clone(),
|
||||
AlertVariant::Warning => theme.alert.warning_background_color.clone(),
|
||||
AlertVariant::Error => theme.alert.error_background_color.clone(),
|
||||
}
|
||||
}
|
||||
fn theme_border_color(&self, theme: &Theme) -> String {
|
||||
match self {
|
||||
AlertVariant::Success => theme.alert.success_border_color.clone(),
|
||||
AlertVariant::Warning => theme.alert.warning_border_color.clone(),
|
||||
AlertVariant::Error => theme.alert.error_border_color.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Alert(
|
||||
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
|
||||
#[prop(optional, into)] title: Option<MaybeSignal<String>>,
|
||||
#[prop(into)] variant: MaybeSignal<AlertVariant>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
mount_style("alert", include_str!("./alert.css"));
|
||||
let theme = use_theme(Theme::light);
|
||||
|
||||
let css_vars = create_memo({
|
||||
let variant = variant.clone();
|
||||
|
||||
move |_| {
|
||||
let mut css_vars = String::new();
|
||||
|
||||
theme.with(|theme| {
|
||||
let variant = variant.get();
|
||||
css_vars.push_str(&format!(
|
||||
"--thaw-icon-color: {};",
|
||||
variant.theme_icon_color(theme)
|
||||
));
|
||||
css_vars.push_str(&format!(
|
||||
"--thaw-background-color: {};",
|
||||
variant.theme_background_color(theme)
|
||||
));
|
||||
css_vars.push_str(&format!(
|
||||
"--thaw-border-color: {};",
|
||||
variant.theme_border_color(theme)
|
||||
));
|
||||
});
|
||||
|
||||
css_vars
|
||||
}
|
||||
});
|
||||
let icon = create_memo(move |_| match variant.get() {
|
||||
AlertVariant::Success => icondata_ai::AiCheckCircleFilled,
|
||||
AlertVariant::Warning => icondata_ai::AiExclamationCircleFilled,
|
||||
AlertVariant::Error => icondata_ai::AiCloseCircleFilled,
|
||||
});
|
||||
|
||||
view! {
|
||||
<div
|
||||
class=class_list!["thaw-alert", class.map(| c | move || c.get())]
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
<Icon icon class="thaw-alert__icon"/>
|
||||
<div>
|
||||
<OptionComp value=title let:title>
|
||||
<div class="thaw-alert__header">{move || title.get()}</div>
|
||||
</OptionComp>
|
||||
<div class="thaw-alert__content">{children()}</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
use crate::theme::ThemeMethod;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AlertTheme {
|
||||
pub success_background_color: String,
|
||||
pub success_border_color: String,
|
||||
pub warning_background_color: String,
|
||||
pub warning_border_color: String,
|
||||
pub error_background_color: String,
|
||||
pub error_border_color: String,
|
||||
}
|
||||
|
||||
impl ThemeMethod for AlertTheme {
|
||||
fn light() -> Self {
|
||||
Self {
|
||||
success_background_color: "#edf7f2".into(),
|
||||
success_border_color: "#c5e7d5".into(),
|
||||
warning_background_color: "#fef7ed".into(),
|
||||
warning_border_color: "#fae0b5".into(),
|
||||
error_background_color: "#fbeef1".into(),
|
||||
error_border_color: "#f3cbd3".into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn dark() -> Self {
|
||||
Self {
|
||||
success_background_color: "#2a947d40".into(),
|
||||
success_border_color: "#2a947d59".into(),
|
||||
warning_background_color: "#f08a0040".into(),
|
||||
warning_border_color: "#f08a0059".into(),
|
||||
error_background_color: "#d03a5240".into(),
|
||||
error_border_color: "#d03a5259".into(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
mod accordion;
|
||||
mod alert;
|
||||
mod anchor;
|
||||
mod auto_complete;
|
||||
mod avatar;
|
||||
|
@ -24,13 +23,13 @@ mod input;
|
|||
mod layout;
|
||||
mod loading_bar;
|
||||
mod message;
|
||||
mod message_bar;
|
||||
mod modal;
|
||||
mod nav;
|
||||
mod popover;
|
||||
mod progress;
|
||||
mod radio;
|
||||
mod scrollbar;
|
||||
mod select;
|
||||
mod skeleton;
|
||||
mod slider;
|
||||
mod space;
|
||||
|
@ -47,7 +46,6 @@ mod time_picker;
|
|||
mod upload;
|
||||
|
||||
pub use accordion::*;
|
||||
pub use alert::*;
|
||||
pub use anchor::*;
|
||||
pub use auto_complete::*;
|
||||
pub use avatar::*;
|
||||
|
@ -72,13 +70,13 @@ pub use input::*;
|
|||
pub use layout::*;
|
||||
pub use loading_bar::*;
|
||||
pub use message::*;
|
||||
pub use message_bar::*;
|
||||
pub use modal::*;
|
||||
pub use nav::*;
|
||||
pub use popover::*;
|
||||
pub use progress::*;
|
||||
pub use radio::*;
|
||||
pub use scrollbar::*;
|
||||
pub use select::*;
|
||||
pub use skeleton::*;
|
||||
pub use slider::*;
|
||||
pub use space::*;
|
||||
|
|
|
@ -52,12 +52,12 @@ fn Message(message: MessageType, #[prop(into)] on_close: Callback<Uuid, ()>) ->
|
|||
let theme = use_theme(Theme::light);
|
||||
let css_vars = create_memo(move |_| {
|
||||
let mut css_vars = String::new();
|
||||
theme.with(|theme| {
|
||||
css_vars.push_str(&format!(
|
||||
"--thaw-background-color: {}",
|
||||
theme.message.background_color
|
||||
))
|
||||
});
|
||||
// theme.with(|theme| {
|
||||
// css_vars.push_str(&format!(
|
||||
// "--thaw-background-color: {}",
|
||||
// theme.message.background_color
|
||||
// ))
|
||||
// });
|
||||
css_vars
|
||||
});
|
||||
let style = theme.with_untracked(|theme| format!("color: {};", variant.theme_color(theme)));
|
||||
|
|
94
thaw/src/message_bar/message-bar.css
Normal file
94
thaw/src/message_bar/message-bar.css
Normal file
|
@ -0,0 +1,94 @@
|
|||
.thaw-message-bar {
|
||||
white-space: nowrap;
|
||||
display: grid;
|
||||
grid-template: "icon body secondaryActions actions" 1fr / auto 1fr auto auto;
|
||||
padding-left: var(--spacingHorizontalM);
|
||||
border: var(--strokeWidthThin) solid var(--colorNeutralStroke1);
|
||||
border-radius: var(--borderRadiusMedium);
|
||||
align-items: center;
|
||||
min-height: 36px;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--colorNeutralBackground3);
|
||||
}
|
||||
|
||||
.thaw-message-bar.thaw-message-bar--multiline {
|
||||
grid-template-areas:
|
||||
"icon body actions"
|
||||
"secondaryActions secondaryActions secondaryActions";
|
||||
grid-template-columns: auto 1fr auto;
|
||||
padding-top: var(--spacingVerticalMNudge);
|
||||
align-items: start;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.thaw-message-bar--success {
|
||||
border-color: var(--colorStatusSuccessBorder1);
|
||||
background-color: var(--colorStatusSuccessBackground1);
|
||||
}
|
||||
|
||||
.thaw-message-bar--success > .thaw-message-bar__icon {
|
||||
color: var(--colorStatusSuccessForeground1);
|
||||
}
|
||||
|
||||
.thaw-message-bar--warning {
|
||||
border-color: var(--colorStatusWarningBorder1);
|
||||
background-color: var(--colorStatusWarningBackground1);
|
||||
}
|
||||
|
||||
.thaw-message-bar--warning > .thaw-message-bar__icon {
|
||||
color: var(--colorStatusWarningForeground3);
|
||||
}
|
||||
|
||||
.thaw-message-bar--error {
|
||||
border-color: var(--colorStatusDangerBorder1);
|
||||
background-color: var(--colorStatusDangerBackground1);
|
||||
}
|
||||
|
||||
.thaw-message-bar--error > .thaw-message-bar__icon {
|
||||
color: var(--colorStatusDangerForeground1);
|
||||
}
|
||||
|
||||
.thaw-message-bar__icon {
|
||||
grid-area: icon;
|
||||
font-size: var(--fontSizeBase500);
|
||||
margin-right: var(--spacingHorizontalS);
|
||||
color: var(--colorNeutralForeground3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.thaw-message-bar__icon > svg {
|
||||
display: inline;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.thaw-message-bar-body {
|
||||
font-family: var(--fontFamilyBase);
|
||||
font-size: var(--fontSizeBase300);
|
||||
font-weight: var(--fontWeightRegular);
|
||||
line-height: var(--lineHeightBase300);
|
||||
grid-area: body;
|
||||
padding-right: var(--spacingHorizontalM);
|
||||
}
|
||||
|
||||
.thaw-message-bar-title {
|
||||
font-family: var(--fontFamilyBase);
|
||||
font-size: var(--fontSizeBase300);
|
||||
font-weight: var(--fontWeightSemibold);
|
||||
line-height: var(--lineHeightBase300);
|
||||
}
|
||||
|
||||
.thaw-message-bar-title::after {
|
||||
content: " ";
|
||||
}
|
||||
|
||||
.thaw-message-bar-actions {
|
||||
grid-area: secondaryActions;
|
||||
display: flex;
|
||||
column-gap: var(--spacingHorizontalM);
|
||||
padding-right: var(--spacingHorizontalM);
|
||||
}
|
||||
.tha-message-bar-actions__container-action {
|
||||
grid-area: actions;
|
||||
padding-right: var(--spacingHorizontalM);
|
||||
}
|
91
thaw/src/message_bar/message_bar.rs
Normal file
91
thaw/src/message_bar/message_bar.rs
Normal file
|
@ -0,0 +1,91 @@
|
|||
use leptos::*;
|
||||
use thaw_utils::{class_list, mount_style, StoredMaybeSignal};
|
||||
|
||||
#[component]
|
||||
pub fn MessageBar(
|
||||
#[prop(optional, into)] layout: MaybeSignal<MessageBarLayout>,
|
||||
#[prop(optional, into)] intent: MaybeSignal<MessageBarIntent>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
mount_style("message-bar", include_str!("./message-bar.css"));
|
||||
let intent: StoredMaybeSignal<_> = intent.into();
|
||||
|
||||
view! {
|
||||
<div
|
||||
class=class_list![
|
||||
"thaw-message-bar",
|
||||
move || format!("thaw-message-bar--{}", intent.get().as_str()),
|
||||
move || format!("thaw-message-bar--{}", layout.get().as_str())
|
||||
]
|
||||
role="group"
|
||||
>
|
||||
<div class="thaw-message-bar__icon">
|
||||
{
|
||||
move || match intent.get() {
|
||||
MessageBarIntent::Info => view! {
|
||||
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20">
|
||||
<path 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" fill="currentColor"></path>
|
||||
</svg>
|
||||
},
|
||||
MessageBarIntent::Success => view! {
|
||||
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20">
|
||||
<path 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" fill="currentColor">
|
||||
</path>
|
||||
</svg>
|
||||
},
|
||||
MessageBarIntent::Warning => view! {
|
||||
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20">
|
||||
<path 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" fill="currentColor">
|
||||
</path>
|
||||
</svg>
|
||||
},
|
||||
MessageBarIntent::Error => view! {
|
||||
<svg fill="currentColor" aria-hidden="true" width="1em" height="1em" viewBox="0 0 20 20">
|
||||
<path 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" fill="currentColor">
|
||||
</path>
|
||||
</svg>
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</div>
|
||||
{children()}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub enum MessageBarIntent {
|
||||
#[default]
|
||||
Info,
|
||||
Success,
|
||||
Warning,
|
||||
Error,
|
||||
}
|
||||
|
||||
impl MessageBarIntent {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
MessageBarIntent::Info => "into",
|
||||
MessageBarIntent::Success => "success",
|
||||
MessageBarIntent::Warning => "warning",
|
||||
MessageBarIntent::Error => "error",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub enum MessageBarLayout {
|
||||
#[default]
|
||||
Singleline,
|
||||
Multiline,
|
||||
}
|
||||
|
||||
impl MessageBarLayout {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
MessageBarLayout::Singleline => "singleline",
|
||||
MessageBarLayout::Multiline => "multiline",
|
||||
}
|
||||
}
|
||||
}
|
21
thaw/src/message_bar/message_bar_actions.rs
Normal file
21
thaw/src/message_bar/message_bar_actions.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn MessageBarActions(
|
||||
message_bar_container_action: MessageBarContainerAction,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
view! {
|
||||
<div class="thaw-message-bar-actions">
|
||||
{children()}
|
||||
</div>
|
||||
<div class="tha-message-bar-actions__container-action">
|
||||
{(message_bar_container_action.children)()}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
#[slot]
|
||||
pub struct MessageBarContainerAction {
|
||||
children: Children,
|
||||
}
|
10
thaw/src/message_bar/message_bar_body.rs
Normal file
10
thaw/src/message_bar/message_bar_body.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn MessageBarBody(children: Children) -> impl IntoView {
|
||||
view! {
|
||||
<div class="thaw-message-bar-body">
|
||||
{children()}
|
||||
</div>
|
||||
}
|
||||
}
|
10
thaw/src/message_bar/message_bar_title.rs
Normal file
10
thaw/src/message_bar/message_bar_title.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn MessageBarTitle(children: Children) -> impl IntoView {
|
||||
view! {
|
||||
<span class="thaw-message-bar-title">
|
||||
{children()}
|
||||
</span>
|
||||
}
|
||||
}
|
9
thaw/src/message_bar/mod.rs
Normal file
9
thaw/src/message_bar/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
mod message_bar;
|
||||
mod message_bar_actions;
|
||||
mod message_bar_body;
|
||||
mod message_bar_title;
|
||||
|
||||
pub use message_bar::*;
|
||||
pub use message_bar_actions::*;
|
||||
pub use message_bar_body::*;
|
||||
pub use message_bar_title::*;
|
|
@ -88,8 +88,15 @@ pub struct ColorTheme {
|
|||
pub color_palette_dark_orange_foreground_3: String,
|
||||
pub color_palette_dark_orange_border_1: String,
|
||||
|
||||
pub color_status_success_background_1: String,
|
||||
pub color_status_success_foreground_1: String,
|
||||
pub color_status_success_border_1: String,
|
||||
pub color_status_warning_background_1: String,
|
||||
pub color_status_warning_foreground_3: String,
|
||||
pub color_status_warning_border_1: String,
|
||||
pub color_status_danger_background_1: String,
|
||||
pub color_status_danger_foreground_1: String,
|
||||
pub color_status_danger_border_1: String,
|
||||
|
||||
pub color_subtle_background: String,
|
||||
pub color_subtle_background_hover: String,
|
||||
|
@ -193,8 +200,15 @@ impl ColorTheme {
|
|||
color_palette_dark_orange_foreground_3: "#da3b01".into(),
|
||||
color_palette_dark_orange_border_1: "#f4bfab".into(),
|
||||
|
||||
color_status_success_background_1: "#f1faf1".into(),
|
||||
color_status_success_foreground_1: "#0e700e".into(),
|
||||
color_status_success_border_1: "#9fd89f".into(),
|
||||
color_status_warning_background_1: "#fff9f5".into(),
|
||||
color_status_warning_foreground_3: "#bc4b09".into(),
|
||||
color_status_warning_border_1: "#fdcfb4".into(),
|
||||
color_status_danger_background_1: "#fdf3f4".into(),
|
||||
color_status_danger_foreground_1: "#b10e1c".into(),
|
||||
color_status_danger_border_1: "#eeacb2".into(),
|
||||
|
||||
color_subtle_background: "transparent".into(),
|
||||
color_subtle_background_hover: "#f5f5f5".into(),
|
||||
|
@ -298,8 +312,15 @@ impl ColorTheme {
|
|||
color_palette_dark_orange_foreground_3: "#e9835e".into(),
|
||||
color_palette_dark_orange_border_1: "#da3b01".into(),
|
||||
|
||||
color_status_success_background_1: "#052505".into(),
|
||||
color_status_success_foreground_1: "#54b054".into(),
|
||||
color_status_success_border_1: "#107c10".into(),
|
||||
color_status_warning_background_1: "#4a1e04".into(),
|
||||
color_status_warning_foreground_3: "#f98845".into(),
|
||||
color_status_warning_border_1: "#f7630c".into(),
|
||||
color_status_danger_background_1: "#3b0509".into(),
|
||||
color_status_danger_foreground_1: "#dc626d".into(),
|
||||
color_status_danger_border_1: "#c50f1f".into(),
|
||||
|
||||
color_subtle_background: "transparent".into(),
|
||||
color_subtle_background_hover: "#383838".into(),
|
||||
|
|
|
@ -2,7 +2,7 @@ mod color;
|
|||
mod common;
|
||||
|
||||
use self::common::CommonTheme;
|
||||
use crate::{AlertTheme, AnchorTheme, MessageTheme, ProgressTheme};
|
||||
use crate::{AnchorTheme, ProgressTheme};
|
||||
pub use color::ColorTheme;
|
||||
use leptos::*;
|
||||
|
||||
|
@ -16,8 +16,6 @@ pub struct Theme {
|
|||
pub name: String,
|
||||
pub common: CommonTheme,
|
||||
pub color: ColorTheme,
|
||||
pub alert: AlertTheme,
|
||||
pub message: MessageTheme,
|
||||
pub progress: ProgressTheme,
|
||||
pub anchor: AnchorTheme,
|
||||
}
|
||||
|
@ -28,8 +26,6 @@ impl Theme {
|
|||
name: "light".into(),
|
||||
common: CommonTheme::light(),
|
||||
color: ColorTheme::light(),
|
||||
alert: AlertTheme::light(),
|
||||
message: MessageTheme::light(),
|
||||
progress: ProgressTheme::light(),
|
||||
anchor: AnchorTheme::light(),
|
||||
}
|
||||
|
@ -39,8 +35,6 @@ impl Theme {
|
|||
name: "dark".into(),
|
||||
common: CommonTheme::dark(),
|
||||
color: ColorTheme::dark(),
|
||||
alert: AlertTheme::dark(),
|
||||
message: MessageTheme::dark(),
|
||||
progress: ProgressTheme::dark(),
|
||||
anchor: AnchorTheme::dark(),
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue