mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-02 08:34:15 -05:00
refactor: Modal
This commit is contained in:
parent
b52d826073
commit
568e629377
18 changed files with 290 additions and 256 deletions
|
@ -61,6 +61,7 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
|
|||
<Route path="/combobox" view=ComboboxMdPage/>
|
||||
<Route path="/config-provider" view=ConfigProviderMdPage/>
|
||||
<Route path="/date-picker" view=DatePickerMdPage/>
|
||||
<Route path="/dialog" view=DialogMdPage/>
|
||||
<Route path="/divider" view=DividerMdPage/>
|
||||
<Route path="/drawer" view=DrawerMdPage/>
|
||||
<Route path="/grid" view=GridMdPage/>
|
||||
|
@ -71,7 +72,6 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
|
|||
<Route path="/loading-bar" view=LoadingBarMdPage/>
|
||||
// <Route path="/message" view=MessageMdPage/>
|
||||
<Route path="/message-bar" view=MessageBarMdPage/>
|
||||
<Route path="/modal" view=ModalMdPage/>
|
||||
<Route path="/popover" view=PopoverMdPage/>
|
||||
<Route path="/progress-bar" view=ProgressBarMdPage/>
|
||||
<Route path="/radio" view=RadioMdPage/>
|
||||
|
|
|
@ -195,6 +195,10 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
|||
value: "/components/date-picker".into(),
|
||||
label: "Date Picker".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/dialog".into(),
|
||||
label: "Dialog".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/divider".into(),
|
||||
label: "Divider".into(),
|
||||
|
@ -235,10 +239,6 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
|||
value: "/components/message-bar".into(),
|
||||
label: "Message Bar".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/modal".into(),
|
||||
label: "Modal".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/popover".into(),
|
||||
label: "Popover".into(),
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
# Modal
|
||||
# Dialog
|
||||
|
||||
```rust demo
|
||||
let show = create_rw_signal(false);
|
||||
let open = RwSignal::new(false);
|
||||
|
||||
view! {
|
||||
<Button on_click=move |_| show.set(true)>"Open Modal"</Button>
|
||||
<Modal title="title" show>
|
||||
"hello"
|
||||
</Modal>
|
||||
<Button on_click=move |_| open.set(true)>"Open Dialog"</Button>
|
||||
<Dialog open>
|
||||
<DialogSurface>
|
||||
<DialogBody>
|
||||
<DialogTitle>"Dialog title"</DialogTitle>
|
||||
<DialogContent>
|
||||
"Dialog body"
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button appearance=ButtonAppearance::Primary>"Do Something"</Button>
|
||||
</DialogActions>
|
||||
</DialogBody>
|
||||
</DialogSurface>
|
||||
</Dialog>
|
||||
}
|
||||
```
|
||||
|
|
@ -44,6 +44,7 @@ pub fn include_md(_token_stream: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
"ComboboxMdPage" => "../docs/combobox/mod.md",
|
||||
"ConfigProviderMdPage" => "../docs/config_provider/mod.md",
|
||||
"DatePickerMdPage" => "../docs/date_picker/mod.md",
|
||||
"DialogMdPage" => "../docs/dialog/mod.md",
|
||||
"DividerMdPage" => "../docs/divider/mod.md",
|
||||
"DrawerMdPage" => "../docs/drawer/mod.md",
|
||||
"GridMdPage" => "../docs/grid/mod.md",
|
||||
|
@ -54,7 +55,6 @@ pub fn include_md(_token_stream: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
"LoadingBarMdPage" => "../docs/loading_bar/mod.md",
|
||||
// "MessageMdPage" => "../docs/message/mod.md",
|
||||
"MessageBarMdPage" => "../docs/message_bar/mod.md",
|
||||
"ModalMdPage" => "../docs/modal/mod.md",
|
||||
"PopoverMdPage" => "../docs/popover/mod.md",
|
||||
"ProgressBarMdPage" => "../docs/progress_bar/mod.md",
|
||||
"RadioMdPage" => "../docs/radio/mod.md",
|
||||
|
|
|
@ -45,15 +45,6 @@ impl ButtonShape {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub enum ButtonColor {
|
||||
#[default]
|
||||
Primary,
|
||||
Success,
|
||||
Warning,
|
||||
Error,
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Clone)]
|
||||
pub enum ButtonSize {
|
||||
Small,
|
||||
|
@ -78,7 +69,6 @@ pub fn Button(
|
|||
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
|
||||
#[prop(optional, into)] appearance: MaybeSignal<ButtonAppearance>,
|
||||
#[prop(optional, into)] shape: MaybeSignal<ButtonShape>,
|
||||
#[prop(optional, into)] color: MaybeSignal<ButtonColor>,
|
||||
#[prop(optional, into)] size: MaybeSignal<ButtonSize>,
|
||||
#[prop(optional, into)] block: MaybeSignal<bool>,
|
||||
#[prop(optional, into)] icon: OptionalMaybeSignal<icondata_core::Icon>,
|
||||
|
|
|
@ -9,25 +9,10 @@ pub use card_preview::*;
|
|||
use leptos::*;
|
||||
use thaw_utils::{class_list, mount_style, OptionalProp};
|
||||
|
||||
#[slot]
|
||||
pub struct CardHeaderExtra {
|
||||
children: Children,
|
||||
}
|
||||
|
||||
#[slot]
|
||||
pub struct CardFooter {
|
||||
#[prop(default = leptos::MaybeSignal::Static(true), into)]
|
||||
if_: MaybeSignal<bool>,
|
||||
children: ChildrenFn,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Card(
|
||||
#[prop(optional, into)] title: OptionalProp<MaybeSignal<String>>,
|
||||
#[prop(optional)] card_header_extra: Option<CardHeaderExtra>,
|
||||
#[prop(optional, into)] class: OptionalProp<MaybeSignal<String>>,
|
||||
children: Children,
|
||||
#[prop(optional)] card_footer: Option<CardFooter>,
|
||||
) -> impl IntoView {
|
||||
mount_style("card", include_str!("./card.css"));
|
||||
|
||||
|
|
117
thaw/src/dialog/dialog.css
Normal file
117
thaw/src/dialog/dialog.css
Normal file
|
@ -0,0 +1,117 @@
|
|||
.thaw-dialog {
|
||||
z-index: 1000000;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.thaw-dialog-surface__backdrop {
|
||||
inset: 0px;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.thaw-dialog-surface__backdrop.fade-in-transition-enter-active {
|
||||
transition: opacity 0.25s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.thaw-dialog-surface__backdrop.fade-in-transition-leave-active {
|
||||
transition: opacity 0.25s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.thaw-dialog-surface__backdrop.fade-in-transition-enter-from,
|
||||
.thaw-dialog-surface__backdrop.fade-in-transition-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.thaw-dialog-surface__backdrop.fade-in-transition-leave-from,
|
||||
.thaw-dialog-surface__backdrop.fade-in-transition-enter-to {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.thaw-dialog-surface {
|
||||
inset: 0px;
|
||||
padding: 24px;
|
||||
margin: auto;
|
||||
overflow: unset;
|
||||
border: 1px solid var(--colorTransparentStroke);
|
||||
border-radius: var(--borderRadiusXLarge);
|
||||
display: block;
|
||||
user-select: unset;
|
||||
visibility: unset;
|
||||
position: fixed;
|
||||
height: fit-content;
|
||||
max-width: 600px;
|
||||
max-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
background-color: var(--colorNeutralBackground1);
|
||||
color: var(--colorNeutralForeground1);
|
||||
}
|
||||
|
||||
.thaw-dialog-surface.fade-in-scale-up-transition-leave-active {
|
||||
transition: opacity 0.25s cubic-bezier(0.4, 0, 1, 1),
|
||||
transform 0.25s cubic-bezier(0.4, 0, 1, 1);
|
||||
}
|
||||
|
||||
.thaw-dialog-surface.fade-in-scale-up-transition-enter-active {
|
||||
transition: opacity 0.25s cubic-bezier(0, 0, 0.2, 1),
|
||||
transform 0.25s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.thaw-dialog-surface.fade-in-scale-up-transition-enter-from,
|
||||
.thaw-dialog-surface.fade-in-scale-up-transition-leave-to {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
|
||||
.thaw-dialog-surface.fade-in-scale-up-transition-leave-from,
|
||||
.thaw-dialog-surface.fade-in-scale-up-transition-enter-to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.thaw-dialog-body {
|
||||
overflow: unset;
|
||||
gap: 8px;
|
||||
display: grid;
|
||||
max-height: calc(-48px + 100vh);
|
||||
box-sizing: border-box;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-columns: 1fr 1fr auto;
|
||||
}
|
||||
|
||||
.thaw-dialog-title {
|
||||
grid-area: 1 / 1 / 1 / 3;
|
||||
grid-column-end: 4;
|
||||
font-family: var(--fontFamilyBase);
|
||||
font-size: var(--fontSizeBase500);
|
||||
font-weight: var(--fontWeightSemibold);
|
||||
line-height: var(--lineHeightBase500);
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.thaw-dialog-content {
|
||||
padding: var(--strokeWidthThick);
|
||||
margin: calc(var(--strokeWidthThick) * -1);
|
||||
font-family: var(--fontFamilyBase);
|
||||
font-size: var(--fontSizeBase300);
|
||||
font-weight: var(--fontWeightRegular);
|
||||
line-height: var(--lineHeightBase300);
|
||||
overflow-y: auto;
|
||||
min-height: 32px;
|
||||
box-sizing: border-box;
|
||||
grid-area: 2 / 1 / 2 / 4;
|
||||
}
|
||||
|
||||
.thaw-dialog-actions {
|
||||
grid-column-start: 2;
|
||||
justify-self: end;
|
||||
grid-column-end: 4;
|
||||
gap: 8px;
|
||||
height: fit-content;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
grid-row: 3 / 3;
|
||||
}
|
66
thaw/src/dialog/dialog.rs
Normal file
66
thaw/src/dialog/dialog.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
use crate::ConfigInjection;
|
||||
use leptos::*;
|
||||
use thaw_components::{CSSTransition, FocusTrap, Teleport};
|
||||
use thaw_utils::{mount_style, Model};
|
||||
|
||||
#[component]
|
||||
pub fn Dialog(
|
||||
#[prop(into)] open: Model<bool>,
|
||||
#[prop(default = true.into(), into)] mask_closeable: MaybeSignal<bool>,
|
||||
#[prop(default = true, into)] close_on_esc: bool,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
mount_style("dialog", include_str!("./dialog.css"));
|
||||
let config_provider = ConfigInjection::use_();
|
||||
|
||||
let mask_ref = NodeRef::<html::Div>::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! {
|
||||
<Teleport immediate=open.signal()>
|
||||
<FocusTrap disabled=!close_on_esc active=open.signal() on_esc>
|
||||
<div
|
||||
class="thaw-config-provider thaw-dialog"
|
||||
data-thaw-id=config_provider.id().clone()
|
||||
>
|
||||
<CSSTransition
|
||||
node_ref=mask_ref
|
||||
appear=open.get_untracked()
|
||||
show=open.signal()
|
||||
name="fade-in-transition"
|
||||
let:display
|
||||
>
|
||||
<div
|
||||
class="thaw-dialog-surface__backdrop"
|
||||
style=move || display.get()
|
||||
on:click=on_mask_click
|
||||
ref=mask_ref
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
</CSSTransition>
|
||||
<Provider value=DialogInjection{open}>
|
||||
{children()}
|
||||
</Provider>
|
||||
</div>
|
||||
</FocusTrap>
|
||||
</Teleport>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(super) struct DialogInjection {
|
||||
pub open: Model<bool>,
|
||||
}
|
||||
|
||||
impl DialogInjection {
|
||||
pub fn expect_use() -> Self {
|
||||
expect_context::<Self>()
|
||||
}
|
||||
}
|
10
thaw/src/dialog/dialog_actions.rs
Normal file
10
thaw/src/dialog/dialog_actions.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn DialogActions(children: Children) -> impl IntoView {
|
||||
view! {
|
||||
<div class="thaw-dialog-actions">
|
||||
{children()}
|
||||
</div>
|
||||
}
|
||||
}
|
10
thaw/src/dialog/dialog_body.rs
Normal file
10
thaw/src/dialog/dialog_body.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn DialogBody(children: Children) -> impl IntoView {
|
||||
view! {
|
||||
<div class="thaw-dialog-body">
|
||||
{children()}
|
||||
</div>
|
||||
}
|
||||
}
|
10
thaw/src/dialog/dialog_content.rs
Normal file
10
thaw/src/dialog/dialog_content.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn DialogContent(children: Children) -> impl IntoView {
|
||||
view! {
|
||||
<h2 class="thaw-dialog-content">
|
||||
{children()}
|
||||
</h2>
|
||||
}
|
||||
}
|
29
thaw/src/dialog/dialog_surface.rs
Normal file
29
thaw/src/dialog/dialog_surface.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
use super::dialog::DialogInjection;
|
||||
use leptos::*;
|
||||
use thaw_components::CSSTransition;
|
||||
|
||||
#[component]
|
||||
pub fn DialogSurface(children: Children) -> impl IntoView {
|
||||
let dialog = DialogInjection::expect_use();
|
||||
let surface_ref = NodeRef::<html::Div>::new();
|
||||
|
||||
view! {
|
||||
<CSSTransition
|
||||
node_ref=surface_ref
|
||||
appear=dialog.open.get_untracked()
|
||||
show=dialog.open.signal()
|
||||
name="fade-in-scale-up-transition"
|
||||
let:display
|
||||
>
|
||||
<div
|
||||
class="thaw-dialog-surface"
|
||||
ref=surface_ref
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
style:display=move || display.get().map(|_| "none")
|
||||
>
|
||||
{children()}
|
||||
</div>
|
||||
</CSSTransition>
|
||||
}
|
||||
}
|
10
thaw/src/dialog/dialog_title.rs
Normal file
10
thaw/src/dialog/dialog_title.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use leptos::*;
|
||||
|
||||
#[component]
|
||||
pub fn DialogTitle(children: Children) -> impl IntoView {
|
||||
view! {
|
||||
<h2 class="thaw-dialog-title">
|
||||
{children()}
|
||||
</h2>
|
||||
}
|
||||
}
|
13
thaw/src/dialog/mod.rs
Normal file
13
thaw/src/dialog/mod.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
mod dialog;
|
||||
mod dialog_actions;
|
||||
mod dialog_body;
|
||||
mod dialog_content;
|
||||
mod dialog_surface;
|
||||
mod dialog_title;
|
||||
|
||||
pub use dialog::*;
|
||||
pub use dialog_actions::*;
|
||||
pub use dialog_body::*;
|
||||
pub use dialog_content::*;
|
||||
pub use dialog_surface::*;
|
||||
pub use dialog_title::*;
|
|
@ -122,7 +122,7 @@ pub fn Drawer(
|
|||
role="dialog"
|
||||
aria-modal="true"
|
||||
>
|
||||
<Card title>
|
||||
<Card>
|
||||
<Scrollbar content_style="padding: 20px 28px;">
|
||||
{children()}
|
||||
</Scrollbar>
|
||||
|
|
|
@ -14,6 +14,7 @@ mod color_picker;
|
|||
mod combobox;
|
||||
mod config_provider;
|
||||
mod date_picker;
|
||||
mod dialog;
|
||||
mod divider;
|
||||
mod drawer;
|
||||
mod grid;
|
||||
|
@ -24,7 +25,6 @@ mod layout;
|
|||
mod loading_bar;
|
||||
mod message;
|
||||
mod message_bar;
|
||||
mod modal;
|
||||
mod nav;
|
||||
mod popover;
|
||||
mod progress_bar;
|
||||
|
@ -61,6 +61,7 @@ pub use color_picker::*;
|
|||
pub use combobox::*;
|
||||
pub use config_provider::*;
|
||||
pub use date_picker::*;
|
||||
pub use dialog::*;
|
||||
pub use divider::*;
|
||||
pub use drawer::*;
|
||||
pub use grid::*;
|
||||
|
@ -71,7 +72,6 @@ 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_bar::*;
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
use crate::{Card, CardFooter, CardHeader, CardHeaderExtra, Icon, Scrollbar, ScrollbarRef};
|
||||
use leptos::*;
|
||||
use thaw_components::{CSSTransition, FocusTrap, OptionComp, Teleport};
|
||||
use thaw_utils::{mount_style, use_click_position, ComponentRef, Model};
|
||||
|
||||
#[slot]
|
||||
pub struct ModalFooter {
|
||||
children: ChildrenFn,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Modal(
|
||||
#[prop(into)] show: Model<bool>,
|
||||
#[prop(default = true.into(), into)] mask_closeable: MaybeSignal<bool>,
|
||||
#[prop(default = true, into)] close_on_esc: bool,
|
||||
#[prop(default = 2000.into(), into)] z_index: MaybeSignal<i16>,
|
||||
#[prop(default = MaybeSignal::Static("600px".to_string()), into)] width: MaybeSignal<String>,
|
||||
#[prop(optional, into)] title: MaybeSignal<String>,
|
||||
children: Children,
|
||||
#[prop(optional)] modal_footer: Option<ModalFooter>,
|
||||
) -> impl IntoView {
|
||||
mount_style("modal", include_str!("./modal.css"));
|
||||
|
||||
let displayed = RwSignal::new(show.get_untracked());
|
||||
Effect::new(move |prev| {
|
||||
let is_show = show.get();
|
||||
if prev.is_some() && is_show {
|
||||
displayed.set(true);
|
||||
}
|
||||
});
|
||||
|
||||
let on_mask_click = move |_| {
|
||||
if mask_closeable.get_untracked() {
|
||||
show.set(false);
|
||||
}
|
||||
};
|
||||
let on_esc = Callback::new(move |_: ev::KeyboardEvent| {
|
||||
show.set(false);
|
||||
});
|
||||
|
||||
let mask_ref = NodeRef::<html::Div>::new();
|
||||
let scrollbar_ref = ComponentRef::<ScrollbarRef>::new();
|
||||
let modal_ref = NodeRef::<html::Div>::new();
|
||||
|
||||
let click_position = use_click_position();
|
||||
let on_enter = Callback::new(move |_| {
|
||||
let Some(position) = click_position.get_untracked() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Some(scroll_el) = scrollbar_ref.get_untracked() else {
|
||||
return;
|
||||
};
|
||||
let scroll_top = scroll_el.container_scroll_top();
|
||||
|
||||
let Some(modal_el) = modal_ref.get_untracked() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let x = -(modal_el.offset_left() - position.0);
|
||||
let y = -(modal_el.offset_top() - position.1 - scroll_top);
|
||||
|
||||
let _ = modal_el.attr("style", format!("transform-origin: {}px {}px", x, y));
|
||||
});
|
||||
|
||||
view! {
|
||||
<Teleport immediate=show.signal()>
|
||||
<FocusTrap disabled=!close_on_esc active=show.signal() on_esc>
|
||||
<div
|
||||
class="thaw-modal-container"
|
||||
style:z-index=move || z_index.get()
|
||||
style=("--thaw-width", move || width.get())
|
||||
>
|
||||
<Scrollbar
|
||||
content_style="min-height: 100%; display: flex;"
|
||||
style=Signal::derive(move || {
|
||||
if displayed.get() {
|
||||
String::new()
|
||||
} else {
|
||||
String::from("display: none")
|
||||
}
|
||||
})
|
||||
comp_ref=scrollbar_ref
|
||||
>
|
||||
<CSSTransition
|
||||
node_ref=mask_ref
|
||||
appear=show.get_untracked()
|
||||
show=show.signal()
|
||||
name="fade-in-transition"
|
||||
let:display
|
||||
>
|
||||
<div
|
||||
class="thaw-modal-mask"
|
||||
style=move || display.get()
|
||||
on:click=on_mask_click
|
||||
ref=mask_ref
|
||||
></div>
|
||||
</CSSTransition>
|
||||
<CSSTransition
|
||||
node_ref=modal_ref
|
||||
appear=show.get_untracked()
|
||||
show=show.signal()
|
||||
name="fade-in-scale-up-transition"
|
||||
on_enter
|
||||
on_after_leave=move |_| displayed.set(false)
|
||||
let:display
|
||||
>
|
||||
<div
|
||||
class="thaw-modal-body"
|
||||
ref=modal_ref
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
style=move || display.get()
|
||||
>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<span class="thaw-model-title">{move || title.get()}</span>
|
||||
</CardHeader>
|
||||
<CardHeaderExtra slot>
|
||||
<span
|
||||
style="cursor: pointer;"
|
||||
on:click=move |_| show.set(false)
|
||||
>
|
||||
<Icon icon=icondata_ai::AiCloseOutlined/>
|
||||
</span>
|
||||
</CardHeaderExtra>
|
||||
{children()}
|
||||
<CardFooter slot if_=modal_footer.is_some()>
|
||||
<OptionComp value=modal_footer.as_ref() let:footer>
|
||||
{(footer.children)()}
|
||||
</OptionComp>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
</CSSTransition>
|
||||
</Scrollbar>
|
||||
</div>
|
||||
</FocusTrap>
|
||||
</Teleport>
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
.thaw-modal-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
min-height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.thaw-modal-container > * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.thaw-modal-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background-color: #0007;
|
||||
}
|
||||
|
||||
.thaw-modal-mask.fade-in-transition-enter-active {
|
||||
transition: all 0.25s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.thaw-modal-mask.fade-in-transition-leave-active {
|
||||
transition: all 0.25s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.thaw-modal-mask.fade-in-transition-enter-from,
|
||||
.thaw-modal-mask.fade-in-transition-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.thaw-modal-mask.fade-in-transition-leave-from,
|
||||
.thaw-modal-mask.fade-in-transition-enter-to {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.thaw-modal-body {
|
||||
position: relative;
|
||||
margin: auto;
|
||||
width: var(--thaw-width);
|
||||
}
|
||||
|
||||
.thaw-model-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.fade-in-scale-up-transition-leave-active.thaw-modal-body {
|
||||
transform-origin: inherit;
|
||||
transition: opacity 0.25s cubic-bezier(0.4, 0, 1, 1),
|
||||
transform 0.25s cubic-bezier(0.4, 0, 1, 1);
|
||||
}
|
||||
|
||||
.fade-in-scale-up-transition-enter-active.thaw-modal-body {
|
||||
transform-origin: inherit;
|
||||
transition: opacity 0.25s cubic-bezier(0, 0, 0.2, 1),
|
||||
transform 0.25s cubic-bezier(0, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.fade-in-scale-up-transition-enter-from.thaw-modal-body,
|
||||
.fade-in-scale-up-transition-leave-to.thaw-modal-body {
|
||||
opacity: 0;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
|
||||
.fade-in-scale-up-transition-leave-from.thaw-modal-body,
|
||||
.fade-in-scale-up-transition-enter-to.thaw-modal-body {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
Loading…
Add table
Reference in a new issue