use dioxus::prelude::*;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum ShellBreakpoint {
Compact,
#[default]
Medium,
Expanded,
}
impl ShellBreakpoint {
pub fn as_str(&self) -> &'static str {
match self {
Self::Compact => "compact",
Self::Medium => "medium",
Self::Expanded => "expanded",
}
}
pub fn is_compact(&self) -> bool {
*self == Self::Compact
}
pub fn is_mobile(&self) -> bool {
self.is_compact()
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum MobileSidebar {
#[default]
Drawer,
Rail,
Hidden,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum DesktopSidebar {
#[default]
Full,
Rail,
Expandable,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum SheetSnap {
#[default]
Hidden,
Peek,
Half,
Full,
}
impl SheetSnap {
pub fn as_str(&self) -> &'static str {
match self {
Self::Hidden => "hidden",
Self::Peek => "peek",
Self::Half => "half",
Self::Full => "full",
}
}
pub fn is_visible(&self) -> bool {
*self != Self::Hidden
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct BreakpointConfig {
pub compact_below: f64,
pub expanded_above: f64,
}
impl Default for BreakpointConfig {
fn default() -> Self {
Self {
compact_below: 640.0,
expanded_above: 1024.0,
}
}
}
pub fn use_shell_breakpoint(
compact_below: f64,
expanded_above: f64,
) -> ReadSignal<ShellBreakpoint> {
use_shell_breakpoint_runtime(compact_below, expanded_above)
}
fn use_shell_breakpoint_runtime(
compact_below: f64,
expanded_above: f64,
) -> ReadSignal<ShellBreakpoint> {
let mut bp = use_signal(|| ShellBreakpoint::Medium);
use_effect(move || {
spawn(async move {
let compact_max = compact_below - 1.0;
let js = format!(
r#"
function getBp() {{
const w = window.innerWidth;
if (w < {compact_below}) return "compact";
if (w >= {expanded_above}) return "expanded";
return "medium";
}}
dioxus.send(getBp());
const mqlC = window.matchMedia("(max-width: {compact_max}px)");
const mqlE = window.matchMedia("(min-width: {expanded_above}px)");
function onChange() {{ dioxus.send(getBp()); }}
mqlC.addEventListener("change", onChange);
mqlE.addEventListener("change", onChange);
"#
);
let mut eval = document::eval(&js);
while let Ok(v) = eval.recv::<String>().await {
bp.set(match v.as_str() {
"compact" => ShellBreakpoint::Compact,
"medium" => ShellBreakpoint::Medium,
_ => ShellBreakpoint::Expanded,
});
}
bp.set(ShellBreakpoint::Medium);
});
});
bp.into()
}