diff --git a/demo_markdown/docs/drawer/mod.md b/demo_markdown/docs/drawer/mod.md
index 234fd4e..16e34ae 100644
--- a/demo_markdown/docs/drawer/mod.md
+++ b/demo_markdown/docs/drawer/mod.md
@@ -1,54 +1,143 @@
# Drawer
```rust demo
-let show = create_rw_signal(false);
-let placement = create_rw_signal(DrawerPlacement::Top);
+let open = RwSignal::new(false);
+let position = RwSignal::new(DrawerPosition::Top);
-let open = Callback::new(move |new_placement: DrawerPlacement| {
+let open_f = Callback::new(move |new_position: DrawerPosition| {
// Note: Since `show` changes are made in real time,
// please put it in front of `show.set(true)` when changing `placement`.
- placement.set(new_placement);
- show.set(true);
+ position.set(new_position);
+ open.set(true);
});
view! {
- "Top"
- "Right"
- "Bottom"
- "Left"
+ "Top"
+ "Right"
+ "Bottom"
+ "Left"
-
- "Hello"
-
+
+
+
+
+
+ "x"
+
+
+ "Default Drawer"
+
+
+
+ "Drawer content"
+
+
}
```
-### Customize display area
+### Inline
```rust demo
-let show = create_rw_signal(false);
+let open_left = RwSignal::new(false);
+let open_right = RwSignal::new(false);
+let open_buttom = RwSignal::new(false);
view! {
-
-
"Open"
-
- "Current position"
-
+
+
+
+
+
+
+
+ "x"
+
+
+ "Inline Drawer"
+
+
+
+ "Drawer content"
+
+
+
+ "Open left"
+ "Open right"
+ "Open buttom"
+
+
+
+
+
+
+ "x"
+
+
+ "Inline Drawer"
+
+
+
+ "Drawer content"
+
+
+
+
+
+
+
+
+ "x"
+
+
+ "Inline Drawer"
+
+
+
+ "Drawer content"
+
+
}
```
-### Scroll content
+### With Scroll
```rust demo
-let show = create_rw_signal(false);
+let open = RwSignal::new(false);
view! {
-
"Open"
-
- r#"This being said, the world is moving in the direction opposite to Clarke's predictions. In 2001: A Space Odyssey, in the year of 2001, which has already passed, human beings have built magnificent cities in space, and established permanent colonies on the moon, and huge nuclear-powered spacecraft have sailed to Saturn. However, today, in 2018, the walk on the moon has become a distant memory.And the farthest reach of our manned space flights is just as long as the two-hour mileage of a high-speed train passing through my city. At the same time, information technology is developing at an unimaginable speed. With the entire world covered by the Internet, people have gradually lost their interest in space, as they find themselves increasingly comfortable in the space created by IT. Instead of an exploration of the real space, which is full of real difficulties, people now just prefer to experience virtual space through VR. Just like someone said, "You promised me an ocean of stars, but you actually gave me Facebook.""#
-
+
"Open"
+
+
+
+
+
+ "x"
+
+
+ "Default Drawer"
+
+
+
+ r#"This being said, the world is moving in the direction opposite to Clarke's predictions. In 2001: A Space Odyssey, in the year of 2001, which has already passed, human beings have built magnificent cities in space, and established permanent colonies on the moon, and huge nuclear-powered spacecraft have sailed to Saturn. However, today, in 2018, the walk on the moon has become a distant memory.And the farthest reach of our manned space flights is just as long as the two-hour mileage of a high-speed train passing through my city. At the same time, information technology is developing at an unimaginable speed. With the entire world covered by the Internet, people have gradually lost their interest in space, as they find themselves increasingly comfortable in the space created by IT. Instead of an exploration of the real space, which is full of real difficulties, people now just prefer to experience virtual space through VR. Just like someone said, "You promised me an ocean of stars, but you actually gave me Facebook.""#
+
+
}
```
diff --git a/thaw/src/drawer/drawer.css b/thaw/src/drawer/drawer.css
index e3fb15e..dc43684 100644
--- a/thaw/src/drawer/drawer.css
+++ b/thaw/src/drawer/drawer.css
@@ -1,184 +1,49 @@
-.thaw-drawer-container {
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- bottom: 0;
- pointer-events: none;
-}
-
-.thaw-drawer-container > * {
- pointer-events: auto;
-}
-
-.thaw-drawer-mask {
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- bottom: 0;
- background-color: #0007;
-}
-
-.thaw-drawer {
- position: absolute;
-}
-
-.thaw-drawer > .thaw-card {
- border-radius: 0;
- height: 100%;
+.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 > .thaw-card > .thaw-card__header {
- border-bottom: 1px solid var(--thaw-border-color);
- font-size: 16px;
+.thaw-drawer-header-title {
+ column-gap: var(--spacingHorizontalS);
+ justify-content: space-between;
+ align-items: center;
+ display: flex;
}
-.thaw-drawer > .thaw-card > .thaw-card__content {
- flex: 1;
- padding: 0;
- overflow: hidden;
+.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--placement-top {
- height: var(--thaw-height);
- top: 0;
- left: 0;
- right: 0;
+.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--placement-bottom {
- height: var(--thaw-height);
- bottom: 0;
- left: 0;
- right: 0;
+.thaw-drawer-body {
+ padding: 0 var(--spacingHorizontalXXL);
+ flex: 1 1 0%;
+ align-self: stretch;
+ position: relative;
+ z-index: 1;
+ overflow: auto;
}
-.thaw-drawer--placement-left {
- width: var(--thaw-width);
- top: 0;
- bottom: 0;
- left: 0;
-}
-
-.thaw-drawer--placement-right {
- width: var(--thaw-width);
- top: 0;
- bottom: 0;
- right: 0;
-}
-
-.thaw-drawer.slide-in-from-right-transition-leave-active {
- transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
-}
-
-.thaw-drawer.slide-in-from-right-transition-enter-active {
- transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
-}
-
-.thaw-drawer.slide-in-from-right-transition-enter-to {
- transform: translateX(0);
-}
-
-.thaw-drawer.slide-in-from-right-transition-enter-from {
- transform: translateX(100%);
-}
-
-.thaw-drawer.slide-in-from-right-transition-leave-from {
- transform: translateX(0);
-}
-
-.thaw-drawer.slide-in-from-right-transition-leave-to {
- transform: translateX(100%);
-}
-
-.thaw-drawer.slide-in-from-left-transition-leave-active {
- transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
-}
-
-.thaw-drawer.slide-in-from-left-transition-enter-active {
- transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
-}
-
-.thaw-drawer.slide-in-from-left-transition-enter-to {
- transform: translateX(0);
-}
-
-.thaw-drawer.slide-in-from-left-transition-enter-from {
- transform: translateX(-100%);
-}
-
-.thaw-drawer.slide-in-from-left-transition-leave-from {
- transform: translateX(0);
-}
-
-.thaw-drawer.slide-in-from-left-transition-leave-to {
- transform: translateX(-100%);
-}
-
-.thaw-drawer.slide-in-from-top-transition-leave-active {
- transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
-}
-
-.thaw-drawer.slide-in-from-top-transition-enter-active {
- transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
-}
-
-.thaw-drawer.slide-in-from-top-transition-enter-to {
- transform: translateY(0);
-}
-
-.thaw-drawer.slide-in-from-top-transition-enter-from {
- transform: translateY(-100%);
-}
-
-.thaw-drawer.slide-in-from-top-transition-leave-from {
- transform: translateY(0);
-}
-
-.thaw-drawer.slide-in-from-top-transition-leave-to {
- transform: translateY(-100%);
-}
-
-.thaw-drawer.slide-in-from-bottom-transition-leave-active {
- transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
-}
-
-.thaw-drawer.slide-in-from-bottom-transition-enter-active {
- transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
-}
-
-.thaw-drawer.slide-in-from-bottom-transition-enter-to {
- transform: translateY(0);
-}
-
-.thaw-drawer.slide-in-from-bottom-transition-enter-from {
- transform: translateY(100%);
-}
-
-.thaw-drawer.slide-in-from-bottom-transition-leave-from {
- transform: translateY(0);
-}
-
-.thaw-drawer.slide-in-from-bottom-transition-leave-to {
- transform: translateY(100%);
-}
-
-.thaw-drawer-mask.fade-in-transition-enter-active {
- transition: all 0.2s cubic-bezier(0.4, 0, 1, 1);
-}
-
-.thaw-drawer-mask.fade-in-transition-leave-active {
- transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
-}
-
-.thaw-drawer-mask.fade-in-transition-enter-from,
-.thaw-drawer-mask.fade-in-transition-leave-to {
- opacity: 0;
-}
-
-.thaw-drawer-mask.fade-in-transition-leave-from,
-.thaw-drawer-mask.fade-in-transition-enter-to {
- opacity: 1;
+.thaw-drawer-body:last-child {
+ padding-bottom: calc(var(--spacingHorizontalXXL) + 1px);
}
diff --git a/thaw/src/drawer/drawer_body.rs b/thaw/src/drawer/drawer_body.rs
index 9629202..330e7de 100644
--- a/thaw/src/drawer/drawer_body.rs
+++ b/thaw/src/drawer/drawer_body.rs
@@ -1,10 +1,13 @@
+use crate::Scrollbar;
use leptos::*;
#[component]
pub fn DrawerBody(children: Children) -> impl IntoView {
view! {
-
- {children()}
-
+
+
+ {children()}
+
+
}
-}
\ No newline at end of file
+}
diff --git a/thaw/src/drawer/inline-drawer.css b/thaw/src/drawer/inline-drawer.css
new file mode 100644
index 0000000..70760e4
--- /dev/null
+++ b/thaw/src/drawer/inline-drawer.css
@@ -0,0 +1,145 @@
+.thaw-inline-drawer {
+ --thaw-drawer--size: 320px;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: flex-start;
+ position: relative;
+ max-width: 100vw;
+ height: auto;
+ max-height: 100vh;
+ background-color: var(--colorNeutralBackground1);
+ color: var(--colorNeutralForeground1);
+ transform: translate3d(0px, 0px, 0px);
+ opacity: 1;
+ will-change: opacity, transform;
+ transition-property: opacity, transform;
+ transition-duration: var(--durationGentle);
+ box-sizing: border-box;
+ border-right: var(--strokeWidthThin) solid var(--colorTransparentStroke);
+ overflow: hidden;
+}
+
+.thaw-inline-drawer--position-top {
+ height: var(--thaw-drawer--size);
+ top: 0;
+ left: 0;
+ right: 0;
+}
+
+.thaw-inline-drawer--position-bottom {
+ height: var(--thaw-drawer--size);
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+
+.thaw-inline-drawer--position-left {
+ width: var(--thaw-drawer--size);
+ top: 0;
+ bottom: 0;
+ left: 0;
+}
+
+.thaw-inline-drawer--position-right {
+ width: var(--thaw-drawer--size);
+ top: 0;
+ bottom: 0;
+ right: 0;
+}
+
+.thaw-inline-drawer.slide-in-from-right-transition-leave-active {
+ transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
+}
+
+.thaw-inline-drawer.slide-in-from-right-transition-enter-active {
+ transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
+}
+
+.thaw-inline-drawer.slide-in-from-right-transition-enter-to {
+ transform: translateX(0);
+}
+
+.thaw-inline-drawer.slide-in-from-right-transition-enter-from {
+ transform: translateX(100%);
+}
+
+.thaw-inline-drawer.slide-in-from-right-transition-leave-from {
+ transform: translateX(0);
+}
+
+.thaw-inline-drawer.slide-in-from-right-transition-leave-to {
+ transform: translateX(100%);
+}
+
+.thaw-inline-drawer.slide-in-from-left-transition-leave-active {
+ transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
+}
+
+.thaw-inline-drawer.slide-in-from-left-transition-enter-active {
+ transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
+}
+
+.thaw-inline-drawer.slide-in-from-left-transition-enter-to {
+ transform: translateX(0);
+}
+
+.thaw-inline-drawer.slide-in-from-left-transition-enter-from {
+ transform: translateX(-100%);
+}
+
+.thaw-inline-drawer.slide-in-from-left-transition-leave-from {
+ transform: translateX(0);
+}
+
+.thaw-inline-drawer.slide-in-from-left-transition-leave-to {
+ transform: translateX(-100%);
+}
+
+.thaw-inline-drawer.slide-in-from-top-transition-leave-active {
+ transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
+}
+
+.thaw-inline-drawer.slide-in-from-top-transition-enter-active {
+ transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
+}
+
+.thaw-inline-drawer.slide-in-from-top-transition-enter-to {
+ transform: translateY(0);
+}
+
+.thaw-inline-drawer.slide-in-from-top-transition-enter-from {
+ transform: translateY(-100%);
+}
+
+.thaw-inline-drawer.slide-in-from-top-transition-leave-from {
+ transform: translateY(0);
+}
+
+.thaw-inline-drawer.slide-in-from-top-transition-leave-to {
+ transform: translateY(-100%);
+}
+
+.thaw-inline-drawer.slide-in-from-bottom-transition-leave-active {
+ transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
+}
+
+.thaw-inline-drawer.slide-in-from-bottom-transition-enter-active {
+ transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
+}
+
+.thaw-inline-drawer.slide-in-from-bottom-transition-enter-to {
+ transform: translateY(0);
+}
+
+.thaw-inline-drawer.slide-in-from-bottom-transition-enter-from {
+ transform: translateY(100%);
+}
+
+.thaw-inline-drawer.slide-in-from-bottom-transition-leave-from {
+ transform: translateY(0);
+}
+
+.thaw-inline-drawer.slide-in-from-bottom-transition-leave-to {
+ transform: translateY(100%);
+}
diff --git a/thaw/src/drawer/inline_drawer.rs b/thaw/src/drawer/inline_drawer.rs
index 0006eb7..4b51d78 100644
--- a/thaw/src/drawer/inline_drawer.rs
+++ b/thaw/src/drawer/inline_drawer.rs
@@ -1,30 +1,43 @@
+use super::{DrawerPosition, DrawerSize};
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,
+pub fn InlineDrawer(
+ #[prop(into)] open: Model,
+ #[prop(optional, into)] position: MaybeSignal,
+ #[prop(optional, into)] size: MaybeSignal,
children: Children,
) -> impl IntoView {
- mount_style("overlay-drawer", include_str!("./overlay-drawer.css"));
+ mount_style("drawer", include_str!("./drawer.css"));
+ mount_style("inline-drawer", include_str!("./inline-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;
- // };
+ let is_css_transition = RwSignal::new(false);
+ let on_after_enter = move |_| {
+ is_css_transition.set(false);
+ };
+ let lazy_position = Memo::new(move |prev| {
+ let position = position.get().as_str();
+ let Some(prev) = prev else {
+ return position;
+ };
- // if is_css_transition.get() {
- // prev
- // } else {
- // placement
- // }
- "left"
+ if is_css_transition.get() {
+ prev
+ } else {
+ position
+ }
});
+ Effect::new(move |_| {
+ let is_open = open.get();
+ if is_open {
+ is_css_transition.set(true);
+ }
+ });
+ let on_after_leave = move |_| {
+ is_css_transition.set(false);
+ };
view! {
{children()}
diff --git a/thaw/src/drawer/mod.rs b/thaw/src/drawer/mod.rs
index 567e90e..7e5687a 100644
--- a/thaw/src/drawer/mod.rs
+++ b/thaw/src/drawer/mod.rs
@@ -1,169 +1,27 @@
-// mod inline_drawer;
-// mod overlay_drawer;
+mod drawer_body;
+mod drawer_header;
+mod drawer_header_title;
+mod inline_drawer;
+mod overlay_drawer;
-// pub use inline_drawer::*;
-// pub use overlay_drawer::*;
+pub use drawer_body::*;
+pub use drawer_header::*;
+pub use drawer_header_title::*;
+pub use inline_drawer::*;
+pub use overlay_drawer::*;
-use crate::{Card, Scrollbar};
-use leptos::*;
-use thaw_components::{CSSTransition, FocusTrap, Teleport};
-use thaw_utils::{class_list, mount_style, use_lock_html_scroll, Model, OptionalProp};
+use leptos::{MaybeSignal, SignalWith};
-#[component]
-pub fn Drawer(
- #[prop(into)] show: Model
,
- #[prop(default = true.into(), into)] mask_closeable: MaybeSignal,
- #[prop(default = true, into)] close_on_esc: bool,
- #[prop(optional, into)] title: OptionalProp>,
- #[prop(optional, into)] placement: MaybeSignal,
- #[prop(default = MaybeSignal::Static("520px".to_string()), into)] width: MaybeSignal,
- #[prop(default = MaybeSignal::Static("260px".to_string()), into)] height: MaybeSignal,
- #[prop(default = 2000.into(), into)] z_index: MaybeSignal,
- #[prop(optional, into)] mount: DrawerMount,
- #[prop(optional, into)] class: OptionalProp>,
- children: Children,
-) -> impl IntoView {
- mount_style("drawer", include_str!("./drawer.css"));
- let style = create_memo(move |_| {
- let mut style = String::new();
-
- style.push_str(&format!("--thaw-width: {};", width.get()));
- style.push_str(&format!("--thaw-height: {};", height.get()));
-
- style.push_str(&format!("z-index: {};", z_index.get()));
- style
- });
-
- #[component]
- fn DrawerInnr(
- show: Model,
- mask_closeable: MaybeSignal,
- close_on_esc: bool,
- title: OptionalProp>,
- placement: MaybeSignal,
- class: OptionalProp>,
- style: Memo,
- children: Children,
- ) -> impl IntoView {
- let mask_ref = NodeRef::::new();
- let drawer_ref = NodeRef::::new();
-
- let is_css_transition = RwSignal::new(false);
- 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
- }
- });
- let on_after_enter = move |_| {
- is_css_transition.set(false);
- };
-
- let is_lock = RwSignal::new(show.get_untracked());
- Effect::new(move |_| {
- let is_show = show.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 on_mask_click = move |_| {
- if mask_closeable.get_untracked() {
- show.set(false);
- }
- };
- let on_esc = Callback::new(move |_: ev::KeyboardEvent| {
- show.set(false);
- });
-
- view! {
-
-
-
-
-
-
-
-
-
- {children()}
-
-
-
-
-
-
- }
- }
-
- match mount {
- DrawerMount::None => {
- view! { }
- }
- DrawerMount::Body => view! {
-
-
-
- },
- }
-}
-
-#[derive(Clone, Default)]
-pub enum DrawerPlacement {
+#[derive(Clone, Default, Copy)]
+pub enum DrawerPosition {
Top,
Bottom,
- Left,
#[default]
+ Left,
Right,
}
-impl Copy for DrawerPlacement {}
-
-impl DrawerPlacement {
+impl DrawerPosition {
pub fn as_str(&self) -> &'static str {
match self {
Self::Top => "top",
@@ -174,9 +32,25 @@ impl DrawerPlacement {
}
}
-#[derive(Default)]
-pub enum DrawerMount {
- None,
+#[derive(Clone, Default, Copy)]
+pub enum DrawerSize {
#[default]
- Body,
+ Small,
+ Medium,
+ Large,
+ Full,
}
+
+impl DrawerSize {
+ fn as_size_str(&self, position: MaybeSignal) -> &'static str {
+ match self {
+ Self::Small => "320px",
+ Self::Medium => "592px",
+ Self::Large => "940px",
+ Self::Full => position.with(|p| match p {
+ DrawerPosition::Top | DrawerPosition::Bottom => "100vh",
+ DrawerPosition::Left | DrawerPosition::Right => "100vw",
+ }),
+ }
+ }
+}
\ No newline at end of file
diff --git a/thaw/src/drawer/overlay-drawer.css b/thaw/src/drawer/overlay-drawer.css
index 2b74ff9..03069d7 100644
--- a/thaw/src/drawer/overlay-drawer.css
+++ b/thaw/src/drawer/overlay-drawer.css
@@ -18,6 +18,24 @@
background-color: rgba(0, 0, 0, 0.4);
}
+.thaw-overlay-drawer__backdrop.fade-in-transition-enter-active {
+ transition: all 0.2s cubic-bezier(0.4, 0, 1, 1);
+}
+
+.thaw-overlay-drawer__backdrop.fade-in-transition-leave-active {
+ transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
+}
+
+.thaw-overlay-drawer__backdrop.fade-in-transition-enter-from,
+.thaw-overlay-drawer__backdrop.fade-in-transition-leave-to {
+ opacity: 0;
+}
+
+.thaw-overlay-drawer__backdrop.fade-in-transition-leave-from,
+.thaw-overlay-drawer__backdrop.fade-in-transition-enter-to {
+ opacity: 1;
+}
+
.thaw-overlay-drawer {
--thaw-drawer--size: 320px;
display: flex;
@@ -25,11 +43,6 @@
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;
@@ -46,52 +59,127 @@
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-overlay-drawer--position-top {
+ height: var(--thaw-drawer--size);
+ top: 0;
+ left: 0;
+ right: 0;
}
-.thaw-drawer-header-title {
- column-gap: var(--spacingHorizontalS);
- justify-content: space-between;
- align-items: center;
- display: flex;
+.thaw-overlay-drawer--position-bottom {
+ height: var(--thaw-drawer--size);
+ bottom: 0;
+ left: 0;
+ right: 0;
}
-.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-overlay-drawer--position-left {
+ width: var(--thaw-drawer--size);
+ top: 0;
+ bottom: 0;
+ left: 0;
}
-.thaw-drawer-header-title__action {
- margin-right: calc(var(--spacingHorizontalS)* -1);
- grid-row: 1 / 1;
- grid-column-start: 3;
- place-self: start end;
+.thaw-overlay-drawer--position-right {
+ width: var(--thaw-drawer--size);
+ top: 0;
+ bottom: 0;
+ right: 0;
}
-.thaw-drawer-body {
- padding: 0 var(--spacingHorizontalXXL);
- flex: 1 1 0%;
- align-self: stretch;
- position: relative;
- z-index: 1;
- overflow: auto;
+.thaw-overlay-drawer.slide-in-from-right-transition-leave-active {
+ transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
}
-.thaw-drawer-body:last-child {
- padding-bottom: calc(var(--spacingHorizontalXXL) + 1px);
-}
\ No newline at end of file
+.thaw-overlay-drawer.slide-in-from-right-transition-enter-active {
+ transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
+}
+
+.thaw-overlay-drawer.slide-in-from-right-transition-enter-to {
+ transform: translateX(0);
+}
+
+.thaw-overlay-drawer.slide-in-from-right-transition-enter-from {
+ transform: translateX(100%);
+}
+
+.thaw-overlay-drawer.slide-in-from-right-transition-leave-from {
+ transform: translateX(0);
+}
+
+.thaw-overlay-drawer.slide-in-from-right-transition-leave-to {
+ transform: translateX(100%);
+}
+
+.thaw-overlay-drawer.slide-in-from-left-transition-leave-active {
+ transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
+}
+
+.thaw-overlay-drawer.slide-in-from-left-transition-enter-active {
+ transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
+}
+
+.thaw-overlay-drawer.slide-in-from-left-transition-enter-to {
+ transform: translateX(0);
+}
+
+.thaw-overlay-drawer.slide-in-from-left-transition-enter-from {
+ transform: translateX(-100%);
+}
+
+.thaw-overlay-drawer.slide-in-from-left-transition-leave-from {
+ transform: translateX(0);
+}
+
+.thaw-overlay-drawer.slide-in-from-left-transition-leave-to {
+ transform: translateX(-100%);
+}
+
+.thaw-overlay-drawer.slide-in-from-top-transition-leave-active {
+ transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
+}
+
+.thaw-overlay-drawer.slide-in-from-top-transition-enter-active {
+ transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
+}
+
+.thaw-overlay-drawer.slide-in-from-top-transition-enter-to {
+ transform: translateY(0);
+}
+
+.thaw-overlay-drawer.slide-in-from-top-transition-enter-from {
+ transform: translateY(-100%);
+}
+
+.thaw-overlay-drawer.slide-in-from-top-transition-leave-from {
+ transform: translateY(0);
+}
+
+.thaw-overlay-drawer.slide-in-from-top-transition-leave-to {
+ transform: translateY(-100%);
+}
+
+.thaw-overlay-drawer.slide-in-from-bottom-transition-leave-active {
+ transition: transform 0.2s cubic-bezier(0.4, 0, 1, 1);
+}
+
+.thaw-overlay-drawer.slide-in-from-bottom-transition-enter-active {
+ transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);
+}
+
+.thaw-overlay-drawer.slide-in-from-bottom-transition-enter-to {
+ transform: translateY(0);
+}
+
+.thaw-overlay-drawer.slide-in-from-bottom-transition-enter-from {
+ transform: translateY(100%);
+}
+
+.thaw-overlay-drawer.slide-in-from-bottom-transition-leave-from {
+ transform: translateY(0);
+}
+
+.thaw-overlay-drawer.slide-in-from-bottom-transition-leave-to {
+ transform: translateY(100%);
+}
diff --git a/thaw/src/drawer/overlay_drawer.rs b/thaw/src/drawer/overlay_drawer.rs
index e44af6a..8358679 100644
--- a/thaw/src/drawer/overlay_drawer.rs
+++ b/thaw/src/drawer/overlay_drawer.rs
@@ -1,42 +1,45 @@
+use super::{DrawerPosition, DrawerSize};
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,
+pub fn OverlayDrawer(
+ #[prop(into)] open: Model,
+ #[prop(default = true.into(), into)] mask_closeable: MaybeSignal,
+ #[prop(optional, into)] close_on_esc: bool,
+ #[prop(optional, into)] position: MaybeSignal,
+ #[prop(optional, into)] size: MaybeSignal,
children: Children,
) -> impl IntoView {
+ mount_style("drawer", include_str!("./drawer.css"));
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 lazy_position = Memo::new(move |prev| {
+ let position = position.get().as_str();
+ let Some(prev) = prev else {
+ return position;
+ };
+
+ if is_css_transition.get() {
+ prev
+ } else {
+ position
+ }
+ });
let is_lock = RwSignal::new(open.get_untracked());
Effect::new(move |_| {
- let is_show = open.get();
- if is_show {
+ let is_open = open.get();
+ if is_open {
is_lock.set(true);
is_css_transition.set(true);
}
@@ -80,7 +83,7 @@ fn OverlayDrawer(
appear=open.get_untracked()
show=open.signal()
name=Memo::new(move |_| {
- format!("slide-in-from-{}-transition", placement.get())
+ format!("slide-in-from-{}-transition", lazy_position.get())
})
on_after_enter
@@ -89,11 +92,16 @@ fn OverlayDrawer(
>