diff --git a/thaw/src/drawer/drawer_body.rs b/thaw/src/drawer/drawer_body.rs new file mode 100644 index 0000000..9629202 --- /dev/null +++ b/thaw/src/drawer/drawer_body.rs @@ -0,0 +1,10 @@ +use leptos::*; + +#[component] +pub fn DrawerBody(children: Children) -> impl IntoView { + view! { +
+ {children()} +
+ } +} \ No newline at end of file diff --git a/thaw/src/drawer/drawer_header.rs b/thaw/src/drawer/drawer_header.rs new file mode 100644 index 0000000..023cd2e --- /dev/null +++ b/thaw/src/drawer/drawer_header.rs @@ -0,0 +1,10 @@ +use leptos::*; + +#[component] +pub fn DrawerHeader(children: Children) -> impl IntoView { + view! { +
+ {children()} +
+ } +} \ No newline at end of file diff --git a/thaw/src/drawer/drawer_header_title.rs b/thaw/src/drawer/drawer_header_title.rs new file mode 100644 index 0000000..2ff2e09 --- /dev/null +++ b/thaw/src/drawer/drawer_header_title.rs @@ -0,0 +1,26 @@ +use leptos::*; +use thaw_components::OptionComp; + +#[component] +pub fn DrawerHeaderTitle( + #[prop(optional)] drawer_header_title_action: Option, + children: Children, +) -> impl IntoView { + view! { +
+

+ {children()} +

+ +
+ {(action.children)()} +
+
+
+ } +} + +#[slot] +pub struct DrawerHeaderTitleAction { + children: Children, +} diff --git a/thaw/src/drawer/inline_drawer.rs b/thaw/src/drawer/inline_drawer.rs new file mode 100644 index 0000000..0006eb7 --- /dev/null +++ b/thaw/src/drawer/inline_drawer.rs @@ -0,0 +1,51 @@ +use leptos::*; +use thaw_components::CSSTransition; +use thaw_utils::{class_list, mount_style, Model}; + +#[component] +fn InlineDrawer( + open: Model, + mask_closeable: MaybeSignal, + close_on_esc: bool, + // placement: MaybeSignal, + children: Children, +) -> impl IntoView { + mount_style("overlay-drawer", include_str!("./overlay-drawer.css")); + let drawer_ref = NodeRef::::new(); + let placement = Memo::new(move |prev| { + // let placement: = placement.get().as_str(); + // let Some(prev) = prev else { + // return placement; + // }; + + // if is_css_transition.get() { + // prev + // } else { + // placement + // } + "left" + }); + + view! { + +
+ {children()} +
+
+ } +} diff --git a/thaw/src/drawer/mod.rs b/thaw/src/drawer/mod.rs index 89b8eda..567e90e 100644 --- a/thaw/src/drawer/mod.rs +++ b/thaw/src/drawer/mod.rs @@ -1,3 +1,9 @@ +// mod inline_drawer; +// mod overlay_drawer; + +// pub use inline_drawer::*; +// pub use overlay_drawer::*; + use crate::{Card, Scrollbar}; use leptos::*; use thaw_components::{CSSTransition, FocusTrap, Teleport}; diff --git a/thaw/src/drawer/overlay-drawer.css b/thaw/src/drawer/overlay-drawer.css new file mode 100644 index 0000000..2b74ff9 --- /dev/null +++ b/thaw/src/drawer/overlay-drawer.css @@ -0,0 +1,97 @@ +.thaw-overlay-drawer-container { + z-index: 1000000; + position: absolute; + top: 0px; + left: 0px; + right: 0px; + text-align: left; +} + +.thaw-overlay-drawer__backdrop { + will-change: opacity; + transition-timing-function: var(--curveEasyEase); + transition-property: opacity; + opacity: 1; + transition-duration: var(--durationGentle); + inset: 0px; + position: fixed; + background-color: rgba(0, 0, 0, 0.4); +} + +.thaw-overlay-drawer { + --thaw-drawer--size: 320px; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; + position: fixed; + top: 0px; + bottom: 0px; + right: auto; + left: 0px; + width: var(--thaw-drawer--size); + max-width: 100vw; + height: auto; + max-height: 100vh; + background-color: var(--colorNeutralBackground1); + color: var(--colorNeutralForeground1); + box-shadow: var(--shadow64); + transform: translate3d(0px, 0px, 0px); + opacity: 1; + will-change: transform, box-shadow, opacity; + transition-property: transform, box-shadow, opacity; + transition-duration: var(--durationGentle); + box-sizing: border-box; + border-right: var(--strokeWidthThin) solid var(--colorTransparentStroke); + overflow: hidden; +} + +.thaw-drawer-header { + width: 100%; + max-width: 100%; + padding: var(--spacingVerticalXXL) var(--spacingHorizontalXXL) + var(--spacingVerticalS); + gap: var(--spacingHorizontalS); + align-self: stretch; + display: flex; + flex-direction: column; + box-sizing: border-box; + position: relative; + z-index: 2; +} + +.thaw-drawer-header-title { + column-gap: var(--spacingHorizontalS); + justify-content: space-between; + align-items: center; + display: flex; +} + +.thaw-drawer-header-title__heading { + font-family: var(--fontFamilyBase); + font-size: var(--fontSizeBase500); + font-weight: var(--fontWeightSemibold); + line-height: var(--lineHeightBase500); + margin: 0px; + grid-area: 1 / 1 / 1 / 3; +} + +.thaw-drawer-header-title__action { + margin-right: calc(var(--spacingHorizontalS)* -1); + grid-row: 1 / 1; + grid-column-start: 3; + place-self: start end; +} + +.thaw-drawer-body { + padding: 0 var(--spacingHorizontalXXL); + flex: 1 1 0%; + align-self: stretch; + position: relative; + z-index: 1; + overflow: auto; +} + +.thaw-drawer-body:last-child { + padding-bottom: calc(var(--spacingHorizontalXXL) + 1px); +} \ No newline at end of file diff --git a/thaw/src/drawer/overlay_drawer.rs b/thaw/src/drawer/overlay_drawer.rs new file mode 100644 index 0000000..e44af6a --- /dev/null +++ b/thaw/src/drawer/overlay_drawer.rs @@ -0,0 +1,108 @@ +use crate::ConfigInjection; +use leptos::*; +use thaw_components::{CSSTransition, FocusTrap, Teleport}; +use thaw_utils::{class_list, mount_style, use_lock_html_scroll, Model}; + +#[component] +fn OverlayDrawer( + open: Model, + mask_closeable: MaybeSignal, + close_on_esc: bool, + // placement: MaybeSignal, + children: Children, +) -> impl IntoView { + mount_style("overlay-drawer", include_str!("./overlay-drawer.css")); + let config_provider = ConfigInjection::use_(); + let drawer_ref = NodeRef::::new(); + + let placement = Memo::new(move |prev| { + // let placement: = placement.get().as_str(); + // let Some(prev) = prev else { + // return placement; + // }; + + // if is_css_transition.get() { + // prev + // } else { + // placement + // } + "left" + }); + let is_css_transition = RwSignal::new(false); + let on_after_enter = move |_| { + is_css_transition.set(false); + }; + + let is_lock = RwSignal::new(open.get_untracked()); + Effect::new(move |_| { + let is_show = open.get(); + if is_show { + is_lock.set(true); + is_css_transition.set(true); + } + }); + use_lock_html_scroll(is_lock.into()); + let on_after_leave = move |_| { + is_lock.set(false); + is_css_transition.set(false); + }; + + let mask_ref = NodeRef::::new(); + let on_mask_click = move |_| { + if mask_closeable.get_untracked() { + open.set(false); + } + }; + let on_esc = Callback::new(move |_: ev::KeyboardEvent| { + open.set(false); + }); + + view! { + + +
+ +
+
+ + + +
+
+
+ } +}