use topcoat::view::{Class, StaticClass, class};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[allow(dead_code)]
pub enum FloatingSide {
Top,
Right,
#[default]
Bottom,
Left,
}
impl FloatingSide {
fn classes(self) -> StaticClass {
match self {
Self::Top => class!(
"mb-1 [position-try-fallbacks:flip-block,flip-inline,flip-block_flip-inline]",
),
Self::Right => class!(
"ml-1 [position-try-fallbacks:flip-inline,flip-block,flip-inline_flip-block,",
"top_span-left,bottom_span-left]",
),
Self::Bottom => class!(
"mt-1 [position-try-fallbacks:flip-block,flip-inline,flip-block_flip-inline]",
),
Self::Left => class!(
"mr-1 [position-try-fallbacks:flip-inline,flip-block,flip-inline_flip-block,",
"top_span-right,bottom_span-right]",
),
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[allow(dead_code)]
pub enum FloatingAlign {
Start,
#[default]
Center,
End,
}
impl FloatingAlign {
fn area(self, side: FloatingSide) -> StaticClass {
match (side, self) {
(FloatingSide::Top, Self::Start) => class!("[position-area:top_span-right]"),
(FloatingSide::Top, Self::Center) => class!("[position-area:top]"),
(FloatingSide::Top, Self::End) => class!("[position-area:top_span-left]"),
(FloatingSide::Right, Self::Start) => class!("[position-area:right_span-bottom]"),
(FloatingSide::Right, Self::Center) => class!("[position-area:right]"),
(FloatingSide::Right, Self::End) => class!("[position-area:right_span-top]"),
(FloatingSide::Bottom, Self::Start) => class!("[position-area:bottom_span-right]"),
(FloatingSide::Bottom, Self::Center) => class!("[position-area:bottom]"),
(FloatingSide::Bottom, Self::End) => class!("[position-area:bottom_span-left]"),
(FloatingSide::Left, Self::Start) => class!("[position-area:left_span-bottom]"),
(FloatingSide::Left, Self::Center) => class!("[position-area:left]"),
(FloatingSide::Left, Self::End) => class!("[position-area:left_span-top]"),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(dead_code)]
pub enum FloatingAnchor {
Invoker,
Scope,
}
impl FloatingAnchor {
fn classes(self) -> StaticClass {
match self {
Self::Invoker => class!(
"inset-auto m-0 [position-anchor:auto]",
"transition-opacity starting:open:opacity-0 motion-reduce:transition-none",
),
Self::Scope => class!("fixed [position-anchor:--floating-anchor]"),
}
}
}
pub const FLOATING_SCOPE: StaticClass =
class!("[anchor-name:--floating-anchor] [anchor-scope:--floating-anchor]");
#[must_use]
pub fn floating_variants(
anchor: FloatingAnchor,
side: FloatingSide,
align: FloatingAlign,
) -> Class<(StaticClass, StaticClass, StaticClass)> {
class!(anchor.classes(), side.classes(), align.area(side))
}