use dioxus::prelude::*;
use dioxus_icons::lucide::X;
use dioxus_primitives::dioxus_attributes::attributes;
use dioxus_primitives::dialog::{
self, DialogCtx, DialogDescriptionProps, DialogRootProps, DialogTitleProps,
};
use dioxus_primitives::merge_attributes;
#[css_module("/src/components/sheet/style.css")]
struct Styles;
#[derive(Debug, Clone, Copy, Default, PartialEq)]
pub enum SheetSide {
Top,
#[default]
Right,
Bottom,
Left,
}
impl SheetSide {
pub fn as_str(&self) -> &'static str {
match self {
SheetSide::Top => "top",
SheetSide::Right => "right",
SheetSide::Bottom => "bottom",
SheetSide::Left => "left",
}
}
}
#[component]
pub fn Sheet(props: DialogRootProps) -> Element {
let content_base = attributes!(div {
class: Styles::dx_sheet,
"data-slot": "sheet-content",
"data-side": SheetSide::Right.as_str(),
});
let content_attributes = merge_attributes(vec![content_base, props.attributes]);
rsx! {
dialog::DialogRoot {
class: Styles::dx_sheet_root,
"data-slot": "sheet-root",
id: props.id,
is_modal: props.is_modal,
open: props.open,
default_open: props.default_open,
on_open_change: props.on_open_change,
dialog::DialogContent {
class: None,
attributes: content_attributes,
{props.children}
}
}
}
}
#[component]
pub fn SheetContentClose(#[props(extends = GlobalAttributes)] attributes: Vec<Attribute>) -> Element {
let base = attributes!(button {
class: Styles::dx_sheet_close,
});
let attributes = merge_attributes(vec![base, attributes]);
rsx! {
SheetClose { attributes,
X { size: "20px" }
}
}
}
#[component]
pub fn SheetHeader(
#[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
children: Element,
) -> Element {
rsx! {
div { class: Styles::dx_sheet_header, "data-slot": "sheet-header", ..attributes, {children} }
}
}
#[component]
pub fn SheetFooter(
#[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
children: Element,
) -> Element {
rsx! {
div { class: Styles::dx_sheet_footer, "data-slot": "sheet-footer", ..attributes, {children} }
}
}
#[component]
pub fn SheetTitle(props: DialogTitleProps) -> Element {
rsx! {
dialog::DialogTitle {
id: props.id,
class: Styles::dx_sheet_title,
"data-slot": "sheet-title",
attributes: props.attributes,
{props.children}
}
}
}
#[component]
pub fn SheetDescription(props: DialogDescriptionProps) -> Element {
rsx! {
dialog::DialogDescription {
id: props.id,
class: Styles::dx_sheet_description,
"data-slot": "sheet-description",
attributes: props.attributes,
{props.children}
}
}
}
#[component]
pub fn SheetClose(
#[props(extends = GlobalAttributes)] attributes: Vec<Attribute>,
r#as: Option<Callback<Vec<Attribute>, Element>>,
children: Element,
) -> Element {
let ctx: DialogCtx = use_context();
let base = attributes! {
button {
onclick: move |_| {
ctx.set_open(false);
}
}
};
let merged = merge_attributes(vec![base, attributes]);
if let Some(dynamic) = r#as {
dynamic.call(merged)
} else {
rsx! {
button { ..merged, {children} }
}
}
}