impulse_ui_kit/
utils.rs

1//! Some utility for UI kit.
2
3/// Utility function to combine classes
4pub fn cn(classes: &[impl AsRef<str>]) -> String {
5  classes
6    .iter()
7    .map(|class| class.as_ref())
8    .filter(|class| !class.is_empty())
9    .collect::<Vec<_>>()
10    .join(" ")
11}
12
13/// Overlay side to show at.
14#[derive(Clone, Copy, PartialEq)]
15#[allow(missing_docs)]
16pub enum OverlaySide {
17  Top,
18  Right,
19  Bottom,
20  Left,
21}
22
23/// Overlay align to show with.
24#[derive(Clone, Copy, PartialEq)]
25#[allow(missing_docs)]
26pub enum OverlayAlign {
27  Start,
28  Center,
29  End,
30}
31
32/// Calculates overlay position based on given positions, side and align.
33#[allow(clippy::too_many_arguments)]
34pub fn calculate_position(
35  trigger_top: f64,
36  trigger_left: f64,
37  trigger_width: f64,
38  trigger_height: f64,
39  content_width: f64,
40  content_height: f64,
41  side: OverlaySide,
42  align: OverlayAlign,
43  side_offset: i32,
44) -> (f64, f64) {
45  let offset = side_offset as f64;
46
47  let (mut top, mut left) = match side {
48    OverlaySide::Top => (trigger_top - content_height - offset, trigger_left),
49    OverlaySide::Bottom => (trigger_top + trigger_height + offset, trigger_left),
50    OverlaySide::Left => (trigger_top, trigger_left - content_width - offset),
51    OverlaySide::Right => (trigger_top, trigger_left + trigger_width + offset),
52  };
53
54  match side {
55    OverlaySide::Top | OverlaySide::Bottom => {
56      left += match align {
57        OverlayAlign::Start => 0.0,
58        OverlayAlign::Center => (trigger_width - content_width) / 2.0,
59        OverlayAlign::End => trigger_width - content_width,
60      };
61    }
62    OverlaySide::Left | OverlaySide::Right => {
63      top += match align {
64        OverlayAlign::Start => 0.0,
65        OverlayAlign::Center => (trigger_height - content_height) / 2.0,
66        OverlayAlign::End => trigger_height - content_height,
67      };
68    }
69  }
70
71  (top, left)
72}