diff --git a/demo_markdown/docs/message/mod.md b/demo_markdown/docs/message/mod.md index 5097663..16a4263 100644 --- a/demo_markdown/docs/message/mod.md +++ b/demo_markdown/docs/message/mod.md @@ -10,7 +10,7 @@ let success = move |_| { message.create( "Success".into(), MessageVariant::Success, - Default::default(), + MessageOptions {closable: true, duration: std::time::Duration::from_secs(0)}, ); }; let warning = move |_| { @@ -33,8 +33,21 @@ view! { } ``` +### MessageProvider Props + +| Name | Type | Default | Desciption | +| --------- | ----------------------------- | ----------------------- | ------------------------------- | +| placement | `MessagePlacement` | `MessagePlacement::Top` | Position to place the messages. | + ### MessageProvider Injection Methods | Name | Type | Description | | ------ | ------------------------------------------------------------------------------ | ------------------------ | | create | `fn(&self, content: String, variant: MessageVariant, options: MessageOptions)` | Use create type message. | + +### MessageOptions fields + +| Name | Type | Default | Description | +| -------- | ----------------- | ------------------------- | --------------------------------------------------------------- | +| duration | `Duration` | `Duration::from_secs(3)` | How long the message will be displayed. 0 for permanent message | +| closable | `bool` | `false` | Can the message be manually closed. | diff --git a/thaw/src/auto_complete/mod.rs b/thaw/src/auto_complete/mod.rs index d21420d..80157d5 100644 --- a/thaw/src/auto_complete/mod.rs +++ b/thaw/src/auto_complete/mod.rs @@ -107,6 +107,7 @@ pub fn AutoComplete( } }); } else if key == *"Enter" { + event.prevent_default(); let option_value = options.with_untracked(|options| { let index = select_option_index.get_untracked(); if options.len() > index { diff --git a/thaw/src/components/teleport/mod.rs b/thaw/src/components/teleport/mod.rs index 4c48b97..cb371f5 100644 --- a/thaw/src/components/teleport/mod.rs +++ b/thaw/src/components/teleport/mod.rs @@ -16,7 +16,7 @@ pub fn Teleport( let mount = mount.unwrap_or_else(|| { document() .body() - .expect("body element not to exist") + .expect("body element to exist") .unchecked_into() }); diff --git a/thaw/src/message/message.css b/thaw/src/message/message.css index cc986e8..9b431b9 100644 --- a/thaw/src/message/message.css +++ b/thaw/src/message/message.css @@ -1,18 +1,57 @@ .thaw-message-container { z-index: 6000; position: fixed; - top: 12px; - left: 0; - right: 0; - height: 0; overflow: visible; display: flex; flex-direction: column; + pointer-events: none; +} + +.thaw-message-container--top { align-items: center; + top: 12px; + left: 0; + right: 0; +} + +.thaw-message-container--bottom { + align-items: center; + bottom: 12px; + left: 0; + right: 0; +} + +.thaw-message-container--bottom-left { + align-items: start; + bottom: 12px; + left: 12px; + right: 0px; +} + +.thaw-message-container--bottom-right { + align-items: end; + bottom: 12px; + left: 0px; + right: 12px; +} + +.thaw-message-container--top-left{ + align-items: start; + top: 12px; + left: 12px; + right: 0px; +} + +.thaw-message-container--top-right { + align-items: end; + top: 12px; + left: 0px; + right: 12px; } .thaw-message-wrapper { margin-bottom: 8px; + position: relative; } .thaw-message { @@ -21,8 +60,8 @@ align-items: center; flex-wrap: nowrap; overflow: hidden; - padding: 10px 20px; + max-width: 75vh; background: var(--thaw-background-color); @@ -30,6 +69,8 @@ border-radius: 3px; box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05); + + pointer-events: all; } .thaw-message__icon { @@ -42,3 +83,9 @@ .thaw-message__content { line-height: 1.6; } + +.thaw-message__close { + margin-left: 10px; + display: flex; + cursor: pointer; +} diff --git a/thaw/src/message/message_environment.rs b/thaw/src/message/message_environment.rs index f015d94..b866d60 100644 --- a/thaw/src/message/message_environment.rs +++ b/thaw/src/message/message_environment.rs @@ -5,15 +5,18 @@ use uuid::Uuid; #[component] pub fn MessageEnvironment( message: MessageType, - #[prop(into)] on_internal_after_leave: Callback, + #[prop(into)] on_internal_after_leave: Callback, ) -> impl IntoView { let (id, content, variant, options) = message; - set_timeout( - move || { - on_internal_after_leave.call(id); - }, - options.duration, - ); - view! { } + if !options.duration.is_zero() { + set_timeout( + move || { + on_internal_after_leave.call(id); + }, + options.duration, + ); + } + + view! { } } diff --git a/thaw/src/message/message_provider.rs b/thaw/src/message/message_provider.rs index 3967abb..1edff6f 100644 --- a/thaw/src/message/message_provider.rs +++ b/thaw/src/message/message_provider.rs @@ -1,12 +1,39 @@ use std::time::Duration; use super::{message_environment::MessageEnvironment, MessageVariant}; -use crate::{components::Teleport, utils::mount_style}; +use crate::{components::Teleport, utils::{class_list::class_list, mount_style}}; use leptos::*; use uuid::Uuid; +#[derive(Default, Clone)] +pub enum MessagePlacement { + #[default] + Top, + TopLeft, + TopRight, + Bottom, + BottomLeft, + BottomRight +} + +impl MessagePlacement { + fn container_style(&self) -> String { + match self { + MessagePlacement::Top => "thaw-message-container--top".to_owned(), + MessagePlacement::TopLeft => "thaw-message-container--top-left".to_owned(), + MessagePlacement::TopRight => "thaw-message-container--top-right".to_owned(), + MessagePlacement::Bottom => "thaw-message-container--bottom".to_owned(), + MessagePlacement::BottomLeft => "thaw-message-container--bottom-left".to_owned(), + MessagePlacement::BottomRight=> "thaw-message-container--bottom-right".to_owned(), + } + } +} + #[component] -pub fn MessageProvider(children: Children) -> impl IntoView { +pub fn MessageProvider( + #[prop(optional)] placement: MessagePlacement, + children: Children, +) -> impl IntoView { mount_style("message", include_str!("./message.css")); let message_list = create_rw_signal::>(vec![]); @@ -25,7 +52,7 @@ pub fn MessageProvider(children: Children) -> impl IntoView { message_list, )> {children()} -
+
Self { Self { duration: Duration::from_secs(3), + closable: false, } } } @@ -82,3 +111,5 @@ impl MessageInjection { pub fn use_message() -> MessageInjection { expect_context::() } + + diff --git a/thaw/src/message/mod.rs b/thaw/src/message/mod.rs index a4dd7b6..1ea50ee 100644 --- a/thaw/src/message/mod.rs +++ b/thaw/src/message/mod.rs @@ -2,9 +2,10 @@ mod message_environment; mod message_provider; mod theme; -use crate::{theme::use_theme, Icon, Theme}; +use crate::{theme::use_theme, Icon, Theme, components::{If, Then}}; use icondata::*; use leptos::*; +use uuid::Uuid; pub use message_provider::*; pub use theme::MessageTheme; @@ -34,7 +35,13 @@ impl MessageVariant { } #[component] -pub(crate) fn Message(variant: MessageVariant, content: String) -> impl IntoView { +pub(crate) fn Message( + variant: MessageVariant, + content: String, + closable: bool, + id: Uuid, + #[prop(into)] on_close: Callback, +) -> impl IntoView { let theme = use_theme(Theme::light); let css_vars = create_memo(move |_| { let mut css_vars = String::new(); @@ -54,7 +61,16 @@ pub(crate) fn Message(variant: MessageVariant, content: String) -> impl IntoView
{content}
+ + +
+ +
+
+
} } + +