1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use crate::{
  component,
  components::{children::Children, Embed, Empty, HStack, VStack},
  event::KeyHandler,
  on_key, render,
};

/// A component for centering its contents.
///
/// For example,
/// ```rust
/// # use intuitive::{component, components::{Centered, Section}, render};
/// #
/// #[component(Root)]
/// fn render() {
///   render! {
///     Centered() {
///       Section(title: "I'm centered")
///     }
///   }
/// }
/// ```
#[component(Centered)]
pub fn render(children: Children<1>, on_key: KeyHandler) {
  let child = children[0].render();

  let on_key = on_key! { [child, on_key]
    event => on_key.handle_or(event, |event| child.on_key(event))
  };

  render! {
    VStack(on_key) {
      Empty()
      HStack() {
        Empty()
        Embed(content: child)
        Empty()
      }
      Empty()
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use crate::{components::Text, element::Any as AnyElement, state::State};

  #[test]
  fn centered_forwards_keys() {
    pub use crate::event::{KeyCode::*, KeyEvent, KeyModifiers};

    let called = State::new(false);
    let on_key_called = called.clone();

    let on_key = on_key! {
      KeyEvent { code: Esc, .. } => on_key_called.set(true),
    };

    let centered: AnyElement = render! {
      Centered() {
        Text(on_key)
      }
    };

    centered.on_key(KeyEvent::new(Esc, KeyModifiers::NONE));

    assert_eq!(called.get(), true);
  }
}