diff --git a/.github/workflows/linux-emscripten.yaml b/.github/workflows/linux-emscripten.yaml
index a2b9e40f9d094dcb1a9dfc6260028a78d52bca17..1c60d402486acc4f2fadc6c6324fd416d91e8012 100644
--- a/.github/workflows/linux-emscripten.yaml
+++ b/.github/workflows/linux-emscripten.yaml
@@ -16,6 +16,5 @@ jobs:
         run: >
           mkdir build;
           cd build;
-          emcmake cmake ..
-          -DFTXUI_BUILD_TESTS=ON;
+          emcmake cmake ..;
           cmake --build . --config Release;
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0831fbf51199ab5a535c9ebe5bf26cbadefe2c9a..f1cc6b97fbd8ca8347ffb884fb035fc92b16bd85 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,7 +15,7 @@ endif()
 
 project(ftxui
   LANGUAGES CXX
-  VERSION 0.3.${git_version}
+  VERSION 0.4.${git_version}
 )
 
 option(FTXUI_BUILD_EXAMPLES "Set to ON to build examples" ON)
@@ -65,6 +65,7 @@ add_library(dom
   src/ftxui/dom/node.cpp
   src/ftxui/dom/node_decorator.cpp
   src/ftxui/dom/paragraph.cpp
+  src/ftxui/dom/reflect.cpp
   src/ftxui/dom/separator.cpp
   src/ftxui/dom/size.cpp
   src/ftxui/dom/spinner.cpp
@@ -76,15 +77,18 @@ add_library(dom
 
 add_library(component
   include/ftxui/component/button.hpp
+  include/ftxui/component/captured_mouse.hpp
   include/ftxui/component/checkbox.hpp
   include/ftxui/component/component.hpp
   include/ftxui/component/container.hpp
   include/ftxui/component/event.hpp
   include/ftxui/component/input.hpp
   include/ftxui/component/menu.hpp
+  include/ftxui/component/mouse.hpp
   include/ftxui/component/radiobox.hpp
   include/ftxui/component/receiver.hpp
   include/ftxui/component/screen_interactive.hpp
+  include/ftxui/component/slider.hpp
   include/ftxui/component/toggle.hpp
   src/ftxui/component/button.cpp
   src/ftxui/component/checkbox.cpp
@@ -96,9 +100,10 @@ add_library(component
   src/ftxui/component/radiobox.cpp
   src/ftxui/component/radiobox.cpp
   src/ftxui/component/screen_interactive.cpp
-  src/ftxui/component/toggle.cpp
+  src/ftxui/component/slider.cpp
   src/ftxui/component/terminal_input_parser.cpp
   src/ftxui/component/terminal_input_parser.hpp
+  src/ftxui/component/toggle.cpp
 )
 
 add_library(ftxui::screen ALIAS screen)
@@ -107,6 +112,14 @@ add_library(ftxui::component ALIAS component)
 
 target_link_libraries(dom PUBLIC screen)
 target_link_libraries(component PUBLIC dom Threads::Threads)
+  find_program(iwyu_path NAMES include-what-you-use iwyu)
+  if(iwyu_path)
+    set_property(TARGET ${lib}
+      PROPERTY ${iwyu_path} -Xiwyu
+        --mapping_file ${CMAKE_CURRENT_SOURCE_DIR}/iwyu.impl
+    )
+  endif()
+
 
 foreach(lib screen dom component)
   target_include_directories(${lib}
@@ -199,7 +212,7 @@ if (FTXUI_BUILD_TESTS AND ${CMAKE_VERSION} VERSION_GREATER "3.11.4")
 
   FetchContent_Declare( googletest
     GIT_REPOSITORY "https://github.com/google/googletest"
-    GIT_TAG        release-1.10.0
+    GIT_TAG        23ef29555ef4789f555f1ba8c51b4c52975f0907
   )
 
   FetchContent_GetProperties(googletest)
diff --git a/doc/example_list.md b/doc/example_list.md
index 3b089bc0691af5579dd48279eb40b8803622f4bd..efddeab1cc4030892dc46331c46dae68199b165b 100644
--- a/doc/example_list.md
+++ b/doc/example_list.md
@@ -30,6 +30,7 @@
 @example ./examples/component/checkbox_in_frame.cpp
 @example ./examples/component/menu2.cpp
 @example ./examples/component/tab_horizontal.cpp
+@example ./examples/component/slider.cpp
 @example ./examples/component/input.cpp
 @example ./examples/component/homescreen.cpp
 @example ./examples/component/radiobox.cpp
diff --git a/examples/component/CMakeLists.txt b/examples/component/CMakeLists.txt
index d20f8995337da33609da3112062c451b97df7956..07dc0b31e2d096808196572f871bc623f40edeed 100644
--- a/examples/component/CMakeLists.txt
+++ b/examples/component/CMakeLists.txt
@@ -13,9 +13,10 @@ example(input)
 example(menu)
 example(menu2)
 example(menu_style)
+example(modal_dialog)
 example(radiobox)
 example(radiobox_in_frame)
+example(slider)
 example(tab_horizontal)
 example(tab_vertical)
 example(toggle)
-example(modal_dialog)
diff --git a/examples/component/button.cpp b/examples/component/button.cpp
index d38f4c17172dec454413ea290d2cd6eeb8b4cfea..dc3ceaf16879d0631cce312e9a7696e28f395236 100644
--- a/examples/component/button.cpp
+++ b/examples/component/button.cpp
@@ -1,8 +1,14 @@
-#include "ftxui/component/button.hpp"
-
-#include "ftxui/component/component.hpp"
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/screen_interactive.hpp"
+#include <functional>  // for function
+#include <memory>      // for unique_ptr, make_u...
+#include <string>      // for wstring
+#include <utility>     // for move
+#include <vector>      // for vector
+
+#include "ftxui/component/button.hpp"              // for Button
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/screen/box.hpp"                    // for ftxui
 
 using namespace ftxui;
 
diff --git a/examples/component/checkbox.cpp b/examples/component/checkbox.cpp
index a0cb0b8699e5a509f6f23c92fc626c9baf0a81c2..47189b640ee64bd7c44cfa63e7f1791dc757c788 100644
--- a/examples/component/checkbox.cpp
+++ b/examples/component/checkbox.cpp
@@ -1,8 +1,7 @@
 #include "ftxui/component/checkbox.hpp"
-
-#include "ftxui/component/component.hpp"
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/screen_interactive.hpp"
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
 
 using namespace ftxui;
 
diff --git a/examples/component/checkbox_in_frame.cpp b/examples/component/checkbox_in_frame.cpp
index 608f2d2f4f3c1de12cdc83342cfac43fdf7c3993..c1f0f9616ee7ddf55f6391fcfc268c9eb270292c 100644
--- a/examples/component/checkbox_in_frame.cpp
+++ b/examples/component/checkbox_in_frame.cpp
@@ -1,10 +1,15 @@
-#include "ftxui/component/checkbox.hpp"
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/input.hpp"
-#include "ftxui/component/menu.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/component/toggle.hpp"
-#include "ftxui/screen/string.hpp"
+#include <memory>   // for allocator_traits<>...
+#include <string>   // for operator+, wstring
+#include <utility>  // for move
+#include <vector>   // for vector
+
+#include "ftxui/component/checkbox.hpp"            // for CheckBox
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/dom/elements.hpp"                  // for Element, operator|
+#include "ftxui/screen/box.hpp"                    // for ftxui
+#include "ftxui/screen/string.hpp"                 // for to_wstring
 
 using namespace ftxui;
 
diff --git a/examples/component/gallery.cpp b/examples/component/gallery.cpp
index 54f4d6cc42638f2beef1d2d2ff5eb2df6ac735bd..d819c54cfe21bd68abec1cbacafb6f471e752f53 100644
--- a/examples/component/gallery.cpp
+++ b/examples/component/gallery.cpp
@@ -1,11 +1,20 @@
-#include "ftxui/component/button.hpp"
-#include "ftxui/component/checkbox.hpp"
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/input.hpp"
-#include "ftxui/component/menu.hpp"
-#include "ftxui/component/radiobox.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/component/toggle.hpp"
+#include <functional>  // for function
+#include <memory>      // for allocator, unique_ptr
+#include <string>      // for wstring
+#include <vector>      // for vector
+
+#include "ftxui/component/button.hpp"              // for Button
+#include "ftxui/component/checkbox.hpp"            // for CheckBox
+#include "ftxui/component/component.hpp"           // for Component, Compone...
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/input.hpp"               // for Input
+#include "ftxui/component/menu.hpp"                // for Menu
+#include "ftxui/component/radiobox.hpp"            // for RadioBox
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/component/slider.hpp"              // for Slider
+#include "ftxui/component/toggle.hpp"              // for Toggle
+#include "ftxui/dom/elements.hpp"                  // for separator, operator|
+#include "ftxui/screen/box.hpp"                    // for ftxui
 
 using namespace ftxui;
 
@@ -20,6 +29,13 @@ class MyComponent : public Component {
   Input input;
   Button button;
 
+  int slider_value_1_ = 12;
+  int slider_value_2_ = 56;
+  int slider_value_3_ = 128;
+  ComponentPtr slider_1_ = Slider(L"R:", &slider_value_1_, 0, 256, 1);
+  ComponentPtr slider_2_ = Slider(L"G:", &slider_value_2_, 0, 256, 1);
+  ComponentPtr slider_3_ = Slider(L"B:", &slider_value_3_, 0, 256, 1);
+
  public:
   MyComponent() {
     Add(&container);
@@ -54,17 +70,26 @@ class MyComponent : public Component {
     input.placeholder = L"Input placeholder";
     container.Add(&input);
 
+    container.Add(slider_1_.get());
+    container.Add(slider_2_.get());
+    container.Add(slider_3_.get());
+
     button.label = L"Quit";
     button.on_click = [&] { on_quit(); };
     container.Add(&button);
   }
 
-  Element Render(std::wstring name, Component& component) {
+  Element Render(std::wstring name, Element element) {
     return hbox({
-        text(name) | size(WIDTH, EQUAL, 8),
-        separator(),
-        component.Render(),
-    });
+               text(name) | size(WIDTH, EQUAL, 8),
+               separator(),
+               element | xflex,
+           }) |
+           xflex;
+  }
+
+  Element Render(std::wstring name, Component& component) {
+    return Render(name, component.Render());
   }
 
   Element Render() override {
@@ -78,11 +103,18 @@ class MyComponent : public Component {
             separator(),
             Render(L"radiobox", radiobox),
             separator(),
-            Render(L"input", input) | size(WIDTH, LESS_THAN, 30),
+            Render(L"input", input) | size(WIDTH, LESS_THAN, 50),
+            separator(),
+            Render(L"slider",  //
+                   vbox({
+                       slider_1_->Render(),
+                       slider_2_->Render(),
+                       slider_3_->Render(),
+                   })),
             separator(),
             Render(L"button", button),
         }) |
-        border;
+        xflex | size(WIDTH, GREATER_THAN, 40) | border;
   }
 
   std::function<void()> on_quit = [] {};
diff --git a/examples/component/homescreen.cpp b/examples/component/homescreen.cpp
index ac8fc83beb63a8584e094dab54a296813ef8f57a..b6c49c798e52b1f5f632bdfa4adf0fb2e795ce18 100644
--- a/examples/component/homescreen.cpp
+++ b/examples/component/homescreen.cpp
@@ -1,14 +1,23 @@
-#include <cmath>
-#include <thread>
+#include <chrono>      // for operator""s, chron...
+#include <cmath>       // for sin
+#include <functional>  // for ref, reference_wra...
+#include <string>      // for allocator, wstring
+#include <thread>      // for sleep_for, thread
+#include <utility>     // for move
+#include <vector>      // for vector
 
-#include "ftxui/component/checkbox.hpp"
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/input.hpp"
-#include "ftxui/component/menu.hpp"
-#include "ftxui/component/radiobox.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/component/toggle.hpp"
-#include "ftxui/screen/string.hpp"
+#include "ftxui/component/checkbox.hpp"            // for CheckBox
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/event.hpp"               // for Event, Event::Custom
+#include "ftxui/component/input.hpp"               // for Input
+#include "ftxui/component/menu.hpp"                // for Menu
+#include "ftxui/component/radiobox.hpp"            // for RadioBox
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/component/toggle.hpp"              // for Toggle
+#include "ftxui/dom/elements.hpp"                  // for text, operator|
+#include "ftxui/screen/box.hpp"                    // for ftxui
+#include "ftxui/screen/color.hpp"                  // for Color, Color::Blue...
 
 using namespace ftxui;
 
diff --git a/examples/component/input.cpp b/examples/component/input.cpp
index 2f2eb51ee691228b146580c9fae6a340bb24d74a..3fc69e1800cd66d873051dcd938767dc84666883 100644
--- a/examples/component/input.cpp
+++ b/examples/component/input.cpp
@@ -1,10 +1,6 @@
 #include "ftxui/component/input.hpp"
-
-#include <iostream>
-
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/screen/string.hpp"
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
 
 using namespace ftxui;
 
diff --git a/examples/component/menu.cpp b/examples/component/menu.cpp
index 1fd33e3e2833e5a67719f1f8c451b7e949f084a3..41860fe425f5a43fe224032dff4ef32c8f3e7e75 100644
--- a/examples/component/menu.cpp
+++ b/examples/component/menu.cpp
@@ -1,10 +1,11 @@
-#include "ftxui/component/menu.hpp"
+#include <functional>  // for function
+#include <iostream>    // for basic_ostream::ope...
+#include <string>      // for wstring, allocator
+#include <vector>      // for vector
 
-#include <chrono>
-#include <iostream>
-#include <thread>
-
-#include "ftxui/component/screen_interactive.hpp"
+#include "ftxui/component/menu.hpp"                // for Menu
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/screen/box.hpp"                    // for ftxui
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/component/menu2.cpp b/examples/component/menu2.cpp
index dd422f6f3123ed89c2f6b8dde9e545524476821c..91aacf8e3b328e5ae7419e1cf40a09e84ee988af 100644
--- a/examples/component/menu2.cpp
+++ b/examples/component/menu2.cpp
@@ -1,11 +1,14 @@
-#include <chrono>
-#include <iostream>
-#include <thread>
+#include <functional>  // for function
+#include <string>      // for wstring, allocator
+#include <vector>      // for vector
 
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/menu.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/screen/string.hpp"
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/menu.hpp"                // for Menu
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/dom/elements.hpp"                  // for text, separator, bold
+#include "ftxui/screen/box.hpp"                    // for ftxui
+#include "ftxui/screen/string.hpp"                 // for to_wstring
 
 using namespace ftxui;
 
diff --git a/examples/component/menu_style.cpp b/examples/component/menu_style.cpp
index 839d26303b4acff0b3671cef80d72797b8c6738b..3fc8879c9ef469cd2dc77bcc26f9b0505e2c0f7f 100644
--- a/examples/component/menu_style.cpp
+++ b/examples/component/menu_style.cpp
@@ -1,10 +1,15 @@
-#include <iostream>
-#include <thread>
+#include <functional>        // for function
+#include <initializer_list>  // for initializer_list
+#include <string>            // for wstring, allocator
+#include <vector>            // for vector
 
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/menu.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/screen/string.hpp"
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/menu.hpp"                // for Menu
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/dom/elements.hpp"                  // for operator|, Element
+#include "ftxui/screen/box.hpp"                    // for ftxui
+#include "ftxui/screen/color.hpp"                  // for Color, Color::Blue
 
 using namespace ftxui;
 
@@ -13,7 +18,14 @@ class MyComponent : public Component {
   MyComponent() {
     Add(&container);
 
-    for (Menu* menu : {&menu_1, &menu_2, &menu_3, &menu_4, &menu_5, &menu_6}) {
+    for (Menu* menu : {
+             &menu_1,
+             &menu_2,
+             &menu_3,
+             &menu_4,
+             &menu_5,
+             &menu_6,
+         }) {
       container.Add(menu);
       menu->entries = {
           L"Monkey", L"Dog", L"Cat", L"Bird", L"Elephant",
@@ -21,22 +33,27 @@ class MyComponent : public Component {
       menu->on_enter = [this]() { on_enter(); };
     }
 
-    menu_2.selected_style = color(Color::Blue);
     menu_2.focused_style = bold | color(Color::Blue);
+    menu_2.selected_style = color(Color::Blue);
+    menu_2.selected_focused_style = bold | color(Color::Blue);
 
     menu_3.selected_style = color(Color::Blue);
     menu_3.focused_style = bgcolor(Color::Blue);
+    menu_3.selected_focused_style = bgcolor(Color::Blue);
 
     menu_4.selected_style = bgcolor(Color::Blue);
     menu_4.focused_style = bgcolor(Color::BlueLight);
+    menu_4.selected_focused_style = bgcolor(Color::BlueLight);
 
     menu_5.normal_style = bgcolor(Color::Blue);
     menu_5.selected_style = bgcolor(Color::Yellow);
     menu_5.focused_style = bgcolor(Color::Red);
+    menu_5.selected_focused_style = bgcolor(Color::Red);
 
     menu_6.normal_style = dim | color(Color::Blue);
     menu_6.selected_style = color(Color::Blue);
     menu_6.focused_style = bold | color(Color::Blue);
+    menu_6.selected_focused_style = bold | color(Color::Blue);
   }
 
   std::function<void()> on_enter = []() {};
diff --git a/examples/component/modal_dialog.cpp b/examples/component/modal_dialog.cpp
index 520fd78fd441975229cc593f0d838a8ff915a1fa..d325e4913d47a44d4815f2a60c1a7fac8c9965fc 100644
--- a/examples/component/modal_dialog.cpp
+++ b/examples/component/modal_dialog.cpp
@@ -1,7 +1,14 @@
-#include "ftxui/component/button.hpp"
-#include "ftxui/component/component.hpp"
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/screen_interactive.hpp"
+#include <functional>  // for function
+#include <memory>      // for allocator_traits<>...
+#include <string>      // for operator+, wstring
+#include <vector>      // for vector
+
+#include "ftxui/component/button.hpp"              // for Button
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/dom/elements.hpp"                  // for Element, operator|
+#include "ftxui/screen/box.hpp"                    // for ftxui
 
 using namespace ftxui;
 
diff --git a/examples/component/radiobox.cpp b/examples/component/radiobox.cpp
index 62d0f1ef98b54e08c0d952c31191f9f3089765f3..0a3a65079866d69c6c8a9a45a0ce6df7073f4adb 100644
--- a/examples/component/radiobox.cpp
+++ b/examples/component/radiobox.cpp
@@ -1,8 +1,5 @@
 #include "ftxui/component/radiobox.hpp"
-
-#include "ftxui/component/component.hpp"
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/screen_interactive.hpp"
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
 
 using namespace ftxui;
 
diff --git a/examples/component/radiobox_in_frame.cpp b/examples/component/radiobox_in_frame.cpp
index 0137425fc8e9d5d82237f942b7940ce1becf3de2..09c86445c131334a3ad4913dd4b3a23b26472ea3 100644
--- a/examples/component/radiobox_in_frame.cpp
+++ b/examples/component/radiobox_in_frame.cpp
@@ -1,11 +1,12 @@
-#include "ftxui/component/checkbox.hpp"
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/input.hpp"
-#include "ftxui/component/menu.hpp"
-#include "ftxui/component/radiobox.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/component/toggle.hpp"
-#include "ftxui/screen/string.hpp"
+#include <string>  // for wstring, operator+
+#include <vector>  // for vector
+
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/radiobox.hpp"            // for RadioBox
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/dom/elements.hpp"                  // for Element, operator|
+#include "ftxui/screen/box.hpp"                    // for ftxui
+#include "ftxui/screen/string.hpp"                 // for to_wstring
 
 using namespace ftxui;
 
diff --git a/examples/component/slider.cpp b/examples/component/slider.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9e7b6f13b27780edb4f6bb48e68aff412f811b4a
--- /dev/null
+++ b/examples/component/slider.cpp
@@ -0,0 +1,84 @@
+#include <functional>  // for function
+#include <memory>      // for allocator, unique_ptr
+#include <string>      // for operator+, to_wstring
+
+#include "ftxui/component/component.hpp"           // for Component, Compone...
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/event.hpp"               // for Event, Event::Escape
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/component/slider.hpp"              // for Slider
+#include "ftxui/dom/elements.hpp"                  // for separator, operator|
+#include "ftxui/screen/box.hpp"                    // for ftxui
+#include "ftxui/screen/color.hpp"                  // for Color
+
+using namespace ftxui;
+
+Element ColorTile(int red, int green, int blue) {
+  return text(L"") | size(WIDTH, GREATER_THAN, 14) |
+         size(HEIGHT, GREATER_THAN, 7) | bgcolor(Color::RGB(red, green, blue));
+}
+
+Element ColorString(int red, int green, int blue) {
+  return text(L"RGB = (" +                     //
+              std::to_wstring(red) + L"," +    //
+              std::to_wstring(green) + L"," +  //
+              std::to_wstring(blue) + L")"     //
+  );
+}
+
+class MyComponent : public Component {
+ public:
+  MyComponent(int* red, int* green, int* blue, std::function<void(void)> quit)
+      : red_(red), green_(green), blue_(blue), quit_(quit) {
+    Add(&container_);
+    container_.Add(slider_red_.get());
+    container_.Add(slider_green_.get());
+    container_.Add(slider_blue_.get());
+  }
+
+  Element Render() {
+    return hbox({
+               ColorTile(*red_, *green_, *blue_),
+               separator(),
+               vbox({
+                   slider_red_->Render(),
+                   separator(),
+                   slider_green_->Render(),
+                   separator(),
+                   slider_blue_->Render(),
+                   separator(),
+                   ColorString(*red_, *green_, *blue_),
+               }) | xflex,
+           }) |
+           border | size(WIDTH, LESS_THAN, 80);
+  }
+
+  bool OnEvent(Event event) {
+    if (event == Event::Return || event == Event::Escape)
+      quit_();
+    return Component::OnEvent(event);
+  }
+
+ private:
+  int* red_;
+  int* green_;
+  int* blue_;
+  Container container_ = Container::Vertical();
+  ComponentPtr slider_red_ = Slider(L"Red  :", red_, 0, 255, 1);
+  ComponentPtr slider_green_ = Slider(L"Green:", green_, 0, 255, 1);
+  ComponentPtr slider_blue_ = Slider(L"Blue :", blue_, 0, 255, 1);
+  std::function<void(void)> quit_;
+};
+
+int main(int argc, const char* argv[]) {
+  auto screen = ScreenInteractive::TerminalOutput();
+  int red = 128;
+  int green = 25;
+  int blue = 100;
+  auto component = MyComponent(&red, &green, &blue, screen.ExitLoopClosure());
+  screen.Loop(&component);
+}
+
+// Copyright 2020 Arthur Sonzogni. All rights reserved.
+// Use of this source code is governed by the MIT license that can be found in
+// the LICENSE file.
diff --git a/examples/component/tab_horizontal.cpp b/examples/component/tab_horizontal.cpp
index a475e4bcf4f3fc62ce86433753a1fc733475088f..8d4b8225c7f56f9e2db79da49835afad93e43a08 100644
--- a/examples/component/tab_horizontal.cpp
+++ b/examples/component/tab_horizontal.cpp
@@ -1,11 +1,14 @@
-#include <iostream>
-#include <thread>
+#include <functional>  // for function
+#include <string>      // for wstring, allocator
+#include <vector>      // for vector
 
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/radiobox.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/component/toggle.hpp"
-#include "ftxui/screen/string.hpp"
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/radiobox.hpp"            // for RadioBox
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/component/toggle.hpp"              // for Toggle
+#include "ftxui/dom/elements.hpp"                  // for Element, operator|
+#include "ftxui/screen/box.hpp"                    // for ftxui
 
 using namespace ftxui;
 
diff --git a/examples/component/tab_vertical.cpp b/examples/component/tab_vertical.cpp
index b32a8d9bb3c516d878867ff1fabeb79deff297c4..398be13dff4156e498299395f45f1dfdc2d94605 100644
--- a/examples/component/tab_vertical.cpp
+++ b/examples/component/tab_vertical.cpp
@@ -1,10 +1,12 @@
-#include <iostream>
+#include <functional>  // for function
+#include <string>      // for wstring, allocator
+#include <vector>      // for vector
 
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/menu.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/component/toggle.hpp"
-#include "ftxui/screen/string.hpp"
+#include "ftxui/component/component.hpp"           // for Component
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/menu.hpp"                // for Menu
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/screen/box.hpp"                    // for ftxui
 
 using namespace ftxui;
 
diff --git a/examples/component/toggle.cpp b/examples/component/toggle.cpp
index ef2cd3ab03e50655cd3f0acc7d9a37fd1243fc46..5ecf09209dcef86d40a8858dcdcda424583131b6 100644
--- a/examples/component/toggle.cpp
+++ b/examples/component/toggle.cpp
@@ -1,12 +1,7 @@
 #include "ftxui/component/toggle.hpp"
-
-#include <chrono>
-#include <iostream>
-#include <thread>
-
-#include "ftxui/component/container.hpp"
-#include "ftxui/component/screen_interactive.hpp"
-#include "ftxui/screen/string.hpp"
+#include "ftxui/component/container.hpp"           // for Container
+#include "ftxui/component/event.hpp"               // for Event, Event::Return
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
 
 using namespace ftxui;
 
diff --git a/examples/dom/border.cpp b/examples/dom/border.cpp
index 57fa7b3a482f54823d78737e8f68effb70a5b045..bd1270125a86a83a51166148dc30933119bc241b 100644
--- a/examples/dom/border.cpp
+++ b/examples/dom/border.cpp
@@ -1,8 +1,9 @@
-#include <chrono>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
-#include <thread>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/color_gallery.cpp b/examples/dom/color_gallery.cpp
index 0775ad15dd8ebd239fb601a039bc26b5e04981c5..8bdd3e73369cb29cea7cf371a0e256b2c63cd5e5 100644
--- a/examples/dom/color_gallery.cpp
+++ b/examples/dom/color_gallery.cpp
@@ -1,14 +1,16 @@
-#include <cmath>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/color_info.hpp>
 #include <ftxui/screen/screen.hpp>
 #include <ftxui/screen/terminal.hpp>
-#include <iostream>
-
-#include "ftxui/screen/string.hpp"
+#include <memory>
+#include <utility>
+#include <vector>
 
 using namespace ftxui;
 #include "./color_info_sorted_2d.ipp"  // ColorInfoSorted2D.
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
 
 int main(int argc, const char* argv[]) {
   // clang-format off
diff --git a/examples/dom/color_info_palette256.cpp b/examples/dom/color_info_palette256.cpp
index 68a1d180f0ad7f526e1ad1db1effaf9d67182dc1..0e172f47f5cbe35707e143c1c7fdf6d73085ad78 100644
--- a/examples/dom/color_info_palette256.cpp
+++ b/examples/dom/color_info_palette256.cpp
@@ -1,10 +1,13 @@
-#include <algorithm>
-#include <cmath>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/color_info.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <ftxui/screen/terminal.hpp>
-#include <iostream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
 #include "ftxui/screen/string.hpp"
 
 using namespace ftxui;
diff --git a/examples/dom/color_truecolor_HSV.cpp b/examples/dom/color_truecolor_HSV.cpp
index ad902bb0799c87880f860cde1b50a83b2af4a753..0aa63171411c2038229cb6ba05c98f135aff5771 100644
--- a/examples/dom/color_truecolor_HSV.cpp
+++ b/examples/dom/color_truecolor_HSV.cpp
@@ -1,10 +1,11 @@
-#include <cmath>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <ftxui/screen/terminal.hpp>
-#include <iostream>
+#include <memory>
+#include <utility>
 
-#include "ftxui/screen/string.hpp"
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/color_truecolor_RGB.cpp b/examples/dom/color_truecolor_RGB.cpp
index d35788e05fc602a229bcf6d65b32ecd123d6b56e..1fd632aeb9b22f3cdc9e2404a4c9a62d32c5edbe 100644
--- a/examples/dom/color_truecolor_RGB.cpp
+++ b/examples/dom/color_truecolor_RGB.cpp
@@ -1,10 +1,11 @@
-#include <cmath>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <ftxui/screen/terminal.hpp>
-#include <iostream>
+#include <memory>
+#include <utility>
 
-#include "ftxui/screen/string.hpp"
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/dbox.cpp b/examples/dom/dbox.cpp
index 2fc712c6be6b24232b9ba08c07b276db6b5484c3..851e3ce4a76b1f7244631e6e74ea1f0777a897f9 100644
--- a/examples/dom/dbox.cpp
+++ b/examples/dom/dbox.cpp
@@ -1,6 +1,9 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/gauge.cpp b/examples/dom/gauge.cpp
index eb2a96ddbcbbf91d7d88fa5fe3450a027681c7cf..ae882e83384da1faf9d0f1ac0864c381f60bd508 100644
--- a/examples/dom/gauge.cpp
+++ b/examples/dom/gauge.cpp
@@ -2,8 +2,12 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
 #include <iostream>
+#include <string>
 #include <thread>
 
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
   using namespace std::chrono_literals;
diff --git a/examples/dom/graph.cpp b/examples/dom/graph.cpp
index 78c8f468248a3b8a425b81dcdb9b1b8b40f31ef7..55d6257279f7378d0b072e28c9494e378770a607 100644
--- a/examples/dom/graph.cpp
+++ b/examples/dom/graph.cpp
@@ -2,9 +2,15 @@
 #include <cmath>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <ftxui/screen/string.hpp>
+#include <functional>
 #include <iostream>
+#include <string>
 #include <thread>
+#include <vector>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
 
 class Graph {
  public:
diff --git a/examples/dom/hflow.cpp b/examples/dom/hflow.cpp
index aa140a634c980d7d033a5e9a13d427a63e28833e..6d2cb9dba08c61633c8fb8e0bf0933a0a18c76bc 100644
--- a/examples/dom/hflow.cpp
+++ b/examples/dom/hflow.cpp
@@ -1,7 +1,11 @@
+#include <stddef.h>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
 #include <ftxui/screen/string.hpp>
-#include <iostream>
+#include <string>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/html_like.cpp b/examples/dom/html_like.cpp
index be565e8ecd596ec19b7c8b0535947027bb36eef4..4f602878cf5892ad914ed695982cbc045c13851e 100644
--- a/examples/dom/html_like.cpp
+++ b/examples/dom/html_like.cpp
@@ -1,10 +1,14 @@
 #include <chrono>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <ftxui/screen/string.hpp>
 #include <iostream>
+#include <string>
 #include <thread>
 
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
+
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
   using namespace std::chrono_literals;
diff --git a/examples/dom/package_manager.cpp b/examples/dom/package_manager.cpp
index 11cbd5f54455eea9269a74c695fed0eb45667227..1ae23b336cb54d606df257d69690ed2b8226e310 100644
--- a/examples/dom/package_manager.cpp
+++ b/examples/dom/package_manager.cpp
@@ -4,9 +4,16 @@
 #include <ftxui/screen/string.hpp>
 #include <iostream>
 #include <list>
+#include <memory>
+#include <string>
 #include <thread>
+#include <utility>
 #include <vector>
 
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
+
 /// @example examples/dom/package_manage.cpp
 
 int main(int argc, const char* argv[]) {
diff --git a/examples/dom/paragraph.cpp b/examples/dom/paragraph.cpp
index adb1f38ff2bfbf4638397421288f2fa79cde771d..9a1a614a818ec56f4835aea4c8dd521044f7971f 100644
--- a/examples/dom/paragraph.cpp
+++ b/examples/dom/paragraph.cpp
@@ -1,7 +1,10 @@
+#include <stdio.h>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <ftxui/screen/string.hpp>
-#include <iostream>
+#include <string>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/separator.cpp b/examples/dom/separator.cpp
index f3bf1a315af80fe6ddc10c67857b6251b084d150..0f258a3490e840bc49f1db4ffa64310ca9d2d38f 100644
--- a/examples/dom/separator.cpp
+++ b/examples/dom/separator.cpp
@@ -1,6 +1,9 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/size.cpp b/examples/dom/size.cpp
index dfeea1d8a3ace0b7da3e4d5b553b4ea25e993b80..bc736d42556feeed1122c488166e654b694e2788 100644
--- a/examples/dom/size.cpp
+++ b/examples/dom/size.cpp
@@ -1,7 +1,12 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
 #include <ftxui/screen/string.hpp>
-#include <iostream>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/spinner.cpp b/examples/dom/spinner.cpp
index 7fff889e36964d537c3cf6e7af8af4b115cf405b..e5c3a262f5b6faa8feaa79ba08dd4f0a5dcff288 100644
--- a/examples/dom/spinner.cpp
+++ b/examples/dom/spinner.cpp
@@ -3,7 +3,13 @@
 #include <ftxui/screen/screen.hpp>
 #include <ftxui/screen/string.hpp>
 #include <iostream>
+#include <string>
 #include <thread>
+#include <utility>
+#include <vector>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/style_blink.cpp b/examples/dom/style_blink.cpp
index 114a0d4a242dab3b4273fbc063d75c5cf3aee04c..64645bf626935f76e4024fd98fd53b315d7c5cb1 100644
--- a/examples/dom/style_blink.cpp
+++ b/examples/dom/style_blink.cpp
@@ -1,6 +1,9 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/style_bold.cpp b/examples/dom/style_bold.cpp
index e395d7844ea2134e1c476f7a6aac732f4b32f2fd..df0dd6e346058f88ff0c24af2b52553601eb927f 100644
--- a/examples/dom/style_bold.cpp
+++ b/examples/dom/style_bold.cpp
@@ -1,6 +1,9 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/style_color.cpp b/examples/dom/style_color.cpp
index f50fddb355f748328bfd71b2f03afd2eeb76bdfd..f96e3ccf296e27ffa8b9faaf472abcb37b04e0ed 100644
--- a/examples/dom/style_color.cpp
+++ b/examples/dom/style_color.cpp
@@ -1,6 +1,10 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/style_dim.cpp b/examples/dom/style_dim.cpp
index 1c4d4469192e1fc5cbbd98779c2f97bd48d31303..61b73d70285c514b66ee8c3b2b9e37a846510ed8 100644
--- a/examples/dom/style_dim.cpp
+++ b/examples/dom/style_dim.cpp
@@ -1,6 +1,9 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/style_gallery.cpp b/examples/dom/style_gallery.cpp
index 0ce864f49f627c044fa1503c7aea896b20b890b0..4439aa637b0d6cf3d17b041ac6247bce600e66fb 100644
--- a/examples/dom/style_gallery.cpp
+++ b/examples/dom/style_gallery.cpp
@@ -1,6 +1,10 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/style_inverted.cpp b/examples/dom/style_inverted.cpp
index 9a191810f8be07f057a2ce77807d23500183b24f..3712deba48c399ffe738d582e73eeb7820a73741 100644
--- a/examples/dom/style_inverted.cpp
+++ b/examples/dom/style_inverted.cpp
@@ -1,6 +1,9 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/style_underlined.cpp b/examples/dom/style_underlined.cpp
index dedf04ab831ae6c88ab0c7da2242e25ff0a4b9c5..52a8d7ad37f75ea3c3942195d7994409d339a56c 100644
--- a/examples/dom/style_underlined.cpp
+++ b/examples/dom/style_underlined.cpp
@@ -1,6 +1,9 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/vbox_hbox.cpp b/examples/dom/vbox_hbox.cpp
index 92d23cdf60562d7ec1461668883e87b259027436..65b55a85baa4799ca6937a2ef062d7ecac35ac7f 100644
--- a/examples/dom/vbox_hbox.cpp
+++ b/examples/dom/vbox_hbox.cpp
@@ -1,6 +1,10 @@
+#include <stdio.h>
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <memory>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 
 int main(int argc, const char* argv[]) {
   using namespace ftxui;
diff --git a/examples/dom/window.cpp b/examples/dom/window.cpp
index df8456175776885d3801bae238db62ac9ce69498..ea2e91724e28d54f521d829a60700044615bb082 100644
--- a/examples/dom/window.cpp
+++ b/examples/dom/window.cpp
@@ -1,6 +1,10 @@
 #include <ftxui/dom/elements.hpp>
 #include <ftxui/screen/screen.hpp>
-#include <iostream>
+#include <vector>
+
+#include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
 
 int main(void) {
   using namespace ftxui;
diff --git a/examples/index.html b/examples/index.html
index fde820ac3c5cd2a9ceef5fc13b3014f678755a7d..4fd3e5c55c419385c67ea96689c78a179ad65dfd 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -69,10 +69,8 @@
     ];
 
     const url_search_params = new URLSearchParams(window.location.search);
-    const example_index = url_search_params.get("id") || 16;
-    const example = example_list[example_index];
-
-    var select = document.getElementById("selectExample"); 
+    const example = url_search_params.get("file") || "./dom/color_gallery.js"
+    const select = document.getElementById("selectExample"); 
 
     for(var i = 0; i < example_list.length; i++) {
         var opt = example_list[i];
@@ -81,9 +79,10 @@
         el.value = opt;
         select.appendChild(el);
     }
-    select.selectedIndex = example_index;
+    select.selectedIndex = example_list.findIndex(path => path == example) || 0;
     select.addEventListener("change", () => {
-      location.href = (location.href).split('?')[0] + "?id=" + select.selectedIndex;
+      location.href = (location.href).split('?')[0] + "?file=" +
+            example_list[select.selectedIndex];
     });
 
     let stdin_buffer = [];
diff --git a/examples/util/print_key_press.cpp b/examples/util/print_key_press.cpp
index 60c36da60a96b41bee9a1396447d991cf9333ef9..3f255b58876bacf68c84f89ee5594f0a0b5d390e 100644
--- a/examples/util/print_key_press.cpp
+++ b/examples/util/print_key_press.cpp
@@ -2,32 +2,83 @@
 // Use of this source code is governed by the MIT license that can be found in
 // the LICENSE file.
 
-#include <chrono>
-#include <ftxui/component/component.hpp>
-#include <ftxui/component/screen_interactive.hpp>
-#include <ftxui/screen/string.hpp>
-#include <iostream>
-#include <thread>
+#include <stddef.h>                                // for size_t
+#include <algorithm>                               // for max
+#include <ftxui/component/component.hpp>           // for Component
+#include <ftxui/component/screen_interactive.hpp>  // for ScreenInteractive
+#include <string>                                  // for allocator, operator+
+#include <utility>                                 // for move
+#include <vector>                                  // for vector
+
+#include "ftxui/component/event.hpp"  // for Event
+#include "ftxui/component/mouse.hpp"  // for Mouse, Mouse::Left
+#include "ftxui/dom/elements.hpp"     // for text, vbox, window
+#include "ftxui/screen/box.hpp"       // for ftxui
 
 using namespace ftxui;
 
+std::wstring Stringify(Event event) {
+  std::wstring out;
+  for (auto& it : event.input())
+    out += L" " + std::to_wstring((unsigned int)it);
+
+  out = L"(" + out + L" ) -> ";
+  if (event.is_character()) {
+    out += std::wstring(L"character(") + event.character() + L")";
+  } else if (event.is_mouse()) {
+    out += L"mouse";
+    switch (event.mouse().button) {
+      case Mouse::Left:
+        out += L"_left";
+        break;
+      case Mouse::Middle:
+        out += L"_middle";
+        break;
+      case Mouse::Right:
+        out += L"_right";
+        break;
+      case Mouse::None:
+        out += L"_none";
+        break;
+      case Mouse::WheelUp:
+        out += L"_wheel_up";
+        break;
+      case Mouse::WheelDown:
+        out += L"_wheel_down";
+        break;
+    }
+    switch (event.mouse().motion) {
+      case Mouse::Pressed:
+        out += L"_pressed";
+        break;
+      case Mouse::Released:
+        out += L"_released";
+        break;
+    }
+    if (event.mouse().control)
+      out += L"_control";
+    if (event.mouse().shift)
+      out += L"_shift";
+    if (event.mouse().meta)
+      out += L"_meta";
+
+    out += L"(" +  //
+           std::to_wstring(event.mouse().x) + L"," +
+           std::to_wstring(event.mouse().y) + L")";
+  } else {
+    out += L"(special)";
+  }
+  return out;
+}
+
 class DrawKey : public Component {
  public:
   ~DrawKey() override = default;
 
   Element Render() override {
     Elements children;
-    for (size_t i = std::max(0, (int)keys.size() - 10); i < keys.size(); ++i) {
-      std::wstring code;
-      for (auto& it : keys[i].input())
-        code += L" " + std::to_wstring((unsigned int)it);
-
-      code = L"(" + code + L" ) -> ";
-      if (keys[i].is_character())
-        code += keys[i].character();
-      else
-        code += L"(special)";
-      children.push_back(text(code));
+    for (size_t i = std::max(0, (int)keys.size() - 20); i < keys.size(); ++i) {
+      children.push_back(text(Stringify(keys[i])));
     }
     return window(text(L"keys"), vbox(std::move(children)));
   }
diff --git a/include/ftxui/component/button.hpp b/include/ftxui/component/button.hpp
index c734e756d6d7114d5aa0e898ec92a7de41862694..e7b190c9ddc7714a4cc7a8698fa27b93d16aaf33 100644
--- a/include/ftxui/component/button.hpp
+++ b/include/ftxui/component/button.hpp
@@ -2,10 +2,14 @@
 #define FTXUI_COMPONENT_BUTTON_HPP
 
 #include <functional>
+#include <string>
 
 #include "ftxui/component/component.hpp"
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/screen/box.hpp"
 
 namespace ftxui {
+struct Event;
 
 /// @brief A button. An action is associated to the click event.
 /// @ingroup dom
@@ -25,6 +29,9 @@ class Button : public Component {
   // Component implementation.
   Element Render() override;
   bool OnEvent(Event) override;
+
+ private:
+  Box box_;
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/component/captured_mouse.hpp b/include/ftxui/component/captured_mouse.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9c69a3af88de5a0227850b4a76fd91f4daf0ecd3
--- /dev/null
+++ b/include/ftxui/component/captured_mouse.hpp
@@ -0,0 +1,18 @@
+#ifndef FTXUI_CAPTURED_MOUSE_HPP
+#define FTXUI_CAPTURED_MOUSE_HPP
+
+#include <memory>
+
+namespace ftxui {
+class CapturedMouseInterface {
+ public:
+  virtual ~CapturedMouseInterface() {}
+};
+using CapturedMouse = std::unique_ptr<CapturedMouseInterface>;
+}  // namespace ftxui
+
+#endif /* end of include guard: FTXUI_CAPTURED_MOUSE_HPP */
+
+// Copyright 2020 Arthur Sonzogni. All rights reserved.
+// Use of this source code is governed by the MIT license that can be found in
+// the LICENSE file.
diff --git a/include/ftxui/component/checkbox.hpp b/include/ftxui/component/checkbox.hpp
index a92b8cd3d158895c0772af71fc72adff8e90254b..214ce5241af9a0c0eb7c4f84891d8da5f16f8c09 100644
--- a/include/ftxui/component/checkbox.hpp
+++ b/include/ftxui/component/checkbox.hpp
@@ -1,11 +1,13 @@
 #ifndef FTXUI_COMPONENT_CHECKBOX_HPP
 #define FTXUI_COMPONENT_CHECKBOX_HPP
 
-#include <functional>
+#include <string>
 
 #include "ftxui/component/component.hpp"
+#include "ftxui/screen/box.hpp"
 
 namespace ftxui {
+struct Event;
 
 /// @brief A Checkbox. It can be checked or unchecked.Display an element on a
 /// ftxui::Screen.
@@ -38,7 +40,10 @@ class CheckBox : public Component {
   bool OnEvent(Event) override;
 
  private:
+  bool OnMouseEvent(Event event);
+
   int cursor_position = 0;
+  Box box_;
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/component/component.hpp b/include/ftxui/component/component.hpp
index 2b7af38e94359bc1c9b2c808e21b746b1d39cc99..9003f1c11f868cf4108eb2ee682179eedec66941 100644
--- a/include/ftxui/component/component.hpp
+++ b/include/ftxui/component/component.hpp
@@ -1,13 +1,17 @@
 #ifndef FTXUI_COMPONENT_COMPONENT_HPP
 #define FTXUI_COMPONENT_COMPONENT_HPP
 
-#include "ftxui/component/event.hpp"
-#include "ftxui/dom/elements.hpp"
+#include <memory>  // for unique_ptr
+#include <vector>  // for vector
+
+#include "ftxui/component/captured_mouse.hpp"  // for CaptureMouse
+#include "ftxui/dom/elements.hpp"             // for Element
 
 namespace ftxui {
 
 class Delegate;
 class Focus;
+struct Event;
 
 /// @brief It implement rendering itself as ftxui::Element. It implement
 /// keyboard navigation by responding to ftxui::Event.
@@ -51,15 +55,19 @@ class Component {
   // Configure all the ancestors to give focus to this component.
   void TakeFocus();
 
+ protected:
+  CapturedMouse CaptureMouse(const Event& event);
+
+  std::vector<Component*> children_;
+
  private:
   Component* parent_ = nullptr;
   void Detach();
   void Attach(Component* parent);
-
- protected:
-  std::vector<Component*> children_;
 };
 
+using ComponentPtr = std::unique_ptr<Component>;
+
 }  // namespace ftxui
 
 #endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_HPP */
diff --git a/include/ftxui/component/container.hpp b/include/ftxui/component/container.hpp
index 7054be194557ec935f9779e3f2b217cfd3644c01..3f78798fbf159862e722d8143b761d68ed80a105 100644
--- a/include/ftxui/component/container.hpp
+++ b/include/ftxui/component/container.hpp
@@ -2,6 +2,8 @@
 #define FTXUI_COMPONENT_CONTAINER_HPP
 
 #include "ftxui/component/component.hpp"
+#include "ftxui/component/event.hpp"
+#include "ftxui/dom/elements.hpp"
 
 namespace ftxui {
 
@@ -36,6 +38,9 @@ class Container : public Component {
 
   int selected_ = 0;
   int* selector_ = nullptr;
+
+ private:
+  bool OnMouseEvent(Event event);
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/component/event.hpp b/include/ftxui/component/event.hpp
index b006f49f4fe7e183ec2d73cd1383cb8a9191ee61..e77feae937be7989d9659a3dc074de61e582ed4d 100644
--- a/include/ftxui/component/event.hpp
+++ b/include/ftxui/component/event.hpp
@@ -1,14 +1,15 @@
 #ifndef FTXUI_COMPONENT_EVENT_HPP
 #define FTXUI_COMPONENT_EVENT_HPP
 
-#include <array>
-#include <ftxui/component/receiver.hpp>
-#include <functional>
-#include <string>
+#include <ftxui/component/mouse.hpp>  // for Mouse
+#include <string>                     // for string, operator==
 #include <vector>
 
 namespace ftxui {
 
+class ScreenInteractive;
+class Component;
+
 /// @brief Represent an event. It can be key press event, a terminal resize, or
 /// more ...
 ///
@@ -26,8 +27,10 @@ struct Event {
   static Event Character(char);
   static Event Character(wchar_t);
 
-  static Event Character(const std::string&);
-  static Event Special(const std::string&);
+  static Event Character(std::string);
+  static Event Special(std::string);
+  static Event Mouse(std::string, Mouse mouse);
+  static Event CursorReporting(std::string, int x, int y);
 
   // --- Arrow ---
   static const Event ArrowLeft;
@@ -54,8 +57,18 @@ struct Event {
   static Event Custom;
 
   //--- Method section ---------------------------------------------------------
-  bool is_character() const { return is_character_; }
+  bool is_character() const { return type_ == Type::Character; }
   wchar_t character() const { return character_; }
+
+  bool is_mouse() const { return type_ == Type::Mouse; }
+  struct Mouse& mouse() {
+    return mouse_;
+  }
+
+  bool is_cursor_reporting() const { return type_ == Type::CursorReporting; }
+  int cursor_x() const { return cursor_.x; }
+  int cursor_y() const { return cursor_.y; }
+
   const std::string& input() const { return input_; }
 
   bool operator==(const Event& other) const { return input_ == other.input_; }
@@ -63,11 +76,30 @@ struct Event {
 
   //--- State section ----------------------------------------------------------
  private:
+  friend Component;
+  friend ScreenInteractive;
+  enum class Type {
+    Unknown,
+    Character,
+    Mouse,
+    CursorReporting,
+  };
+  Type type_ = Type::Unknown;
+
+  struct Cursor {
+    int x;
+    int y;
+  };
+
+  union {
+    wchar_t character_ = U'?';
+    struct Mouse mouse_;
+    struct Cursor cursor_;
+  };
   std::string input_;
-  bool is_character_ = false;
-  wchar_t character_ = U'?';
-};
 
+  ScreenInteractive* screen_ = nullptr;
+};
 
 }  // namespace ftxui
 
diff --git a/include/ftxui/component/input.hpp b/include/ftxui/component/input.hpp
index 9b92b835abc5f432c65c133f41810c8e6192ffcc..fedeacbf5b7ce15587755a1c5b4162fb886bbeec 100644
--- a/include/ftxui/component/input.hpp
+++ b/include/ftxui/component/input.hpp
@@ -2,10 +2,14 @@
 #define FTXUI_COMPONENT_INPUT_H_
 
 #include <functional>
+#include <string>
 
 #include "ftxui/component/component.hpp"
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/screen/box.hpp"
 
 namespace ftxui {
+struct Event;
 
 /// @brief An input box. The user can type text into it.
 /// @ingroup component.
@@ -27,6 +31,11 @@ class Input : public Component {
   // Component implementation.
   Element Render() override;
   bool OnEvent(Event) override;
+
+ private:
+  bool OnMouseEvent(Event);
+  Box input_box_;
+  Box cursor_box_;
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/component/menu.hpp b/include/ftxui/component/menu.hpp
index ece6fe89cbb08a7d8363db119ccc5da73fde5031..8e3f2b1637098d3e66269498bc5c11a18c5f3076 100644
--- a/include/ftxui/component/menu.hpp
+++ b/include/ftxui/component/menu.hpp
@@ -2,11 +2,15 @@
 #define FTXUI_COMPONENT_MENU
 
 #include <functional>
+#include <string>
+#include <vector>
 
 #include "ftxui/component/component.hpp"
 #include "ftxui/dom/elements.hpp"
+#include "ftxui/screen/box.hpp"
 
 namespace ftxui {
+struct Event;
 
 /// @brief A list of items. The user can navigate through them.
 /// @ingroup component
@@ -19,10 +23,12 @@ class Menu : public Component {
   // State.
   std::vector<std::wstring> entries = {};
   int selected = 0;
+  int focused = 0;
 
+  Decorator normal_style = nothing;
   Decorator focused_style = inverted;
   Decorator selected_style = bold;
-  Decorator normal_style = nothing;
+  Decorator selected_focused_style = focused_style | selected_style;
 
   // State update callback.
   std::function<void()> on_change = []() {};
@@ -31,6 +37,11 @@ class Menu : public Component {
   // Component implementation.
   Element Render() override;
   bool OnEvent(Event) override;
+
+ private:
+  bool OnMouseEvent(Event);
+
+  std::vector<Box> boxes_;
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/component/mouse.hpp b/include/ftxui/component/mouse.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..aeeb4909450c1bc11a8510c2a9c2724291c64915
--- /dev/null
+++ b/include/ftxui/component/mouse.hpp
@@ -0,0 +1,44 @@
+#ifndef FTXUI_COMPONENT_MOUSE_HPP
+#define FTXUI_COMPONENT_MOUSE_HPP
+namespace ftxui {
+
+/// @brief A mouse event. It contains the coordinate of the mouse, the button
+/// pressed and the modifier (shift, ctrl, meta).
+/// @ingroup component
+struct Mouse {
+  enum Button {
+    Left = 0,
+    Middle = 1,
+    Right = 2,
+    None = 3,
+    WheelUp = 4,
+    WheelDown = 5,
+  };
+
+  enum Motion {
+    Released = 0,
+    Pressed = 1,
+  };
+
+  // Button
+  Button button;
+
+  // Motion
+  Motion motion;
+
+  // Modifiers:
+  bool shift;
+  bool meta;
+  bool control;
+
+  // Coordinates:
+  int x;
+  int y;
+};
+
+}  // namespace ftxui
+
+// Copyright 2020 Arthur Sonzogni. All rights reserved.
+// Use of this source code is governed by the MIT license that can be found in
+// the LICENSE file.
+#endif /* end of include guard: FTXUI_COMPONENT_MOUSE_HPP */
diff --git a/include/ftxui/component/radiobox.hpp b/include/ftxui/component/radiobox.hpp
index aaf9828af9d2126a239825a09552c23d43d932ff..749324508911da8122adca373c3f5b58bebb32b7 100644
--- a/include/ftxui/component/radiobox.hpp
+++ b/include/ftxui/component/radiobox.hpp
@@ -1,11 +1,15 @@
 #ifndef FTXUI_COMPONENT_RADIOBOX_HPP
 #define FTXUI_COMPONENT_RADIOBOX_HPP
 
-#include <functional>
+#include <string>
+#include <vector>
 
 #include "ftxui/component/component.hpp"
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/screen/box.hpp"
 
 namespace ftxui {
+struct Event;
 
 /// @brief A list of selectable element. One and only one can be selected at
 /// the same time.
@@ -39,7 +43,9 @@ class RadioBox : public Component {
   bool OnEvent(Event) override;
 
  private:
+  bool OnMouseEvent(Event event);
   int cursor_position = 0;
+  std::vector<Box> boxes_;
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/component/receiver.hpp b/include/ftxui/component/receiver.hpp
index 7b85922410f1d6f81d91bd675ac1cb5396921753..8b236c3587da6c0dd4ed4e5d6c97d77f27e9f2e9 100644
--- a/include/ftxui/component/receiver.hpp
+++ b/include/ftxui/component/receiver.hpp
@@ -1,13 +1,13 @@
 #ifndef FTXUI_COMPONENT_RECEIVER_HPP_
 #define FTXUI_COMPONENT_RECEIVER_HPP_
 
-#include <atomic>
-#include <condition_variable>
+#include <atomic>              // for atomic
+#include <condition_variable>  // for condition_variable
 #include <functional>
 #include <iostream>
-#include <memory>
-#include <mutex>
-#include <queue>
+#include <memory>  // for unique_ptr, make_unique
+#include <mutex>   // for mutex, unique_lock
+#include <queue>   // for queue
 
 namespace ftxui {
 
@@ -38,6 +38,7 @@ namespace ftxui {
 // clang-format off
 template<class T> class SenderImpl;
 template<class T> class ReceiverImpl;
+
 template<class T> using Sender = std::unique_ptr<SenderImpl<T>>;
 template<class T> using Receiver = std::unique_ptr<ReceiverImpl<T>>;
 template<class T> Receiver<T> MakeReceiver();
diff --git a/include/ftxui/component/screen_interactive.hpp b/include/ftxui/component/screen_interactive.hpp
index 3327969789c6cecdc8fd0caae9e01e85dce102c4..c3a3251923a80d12841bd74d62a7cc4c3111beba 100644
--- a/include/ftxui/component/screen_interactive.hpp
+++ b/include/ftxui/component/screen_interactive.hpp
@@ -1,19 +1,18 @@
 #ifndef FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
 #define FTXUI_COMPONENT_SCREEN_INTERACTIVE_HPP
 
-#include <atomic>
-#include <condition_variable>
+#include <atomic>  // for atomic
 #include <ftxui/component/receiver.hpp>
-#include <functional>
-#include <memory>
-#include <mutex>
-#include <queue>
+#include <memory>  // for unique_ptr
+#include <string>  // for string
 
+#include "ftxui/component/captured_mouse.hpp"  // for CapturedMouse
 #include "ftxui/component/event.hpp"
-#include "ftxui/screen/screen.hpp"
+#include "ftxui/screen/screen.hpp"  // for Screen
 
 namespace ftxui {
 class Component;
+struct Event;
 
 class ScreenInteractive : public Screen {
  public:
@@ -27,6 +26,7 @@ class ScreenInteractive : public Screen {
   std::function<void()> ExitLoopClosure();
 
   void PostEvent(Event event);
+  CapturedMouse CaptureMouse();
 
  private:
   void Draw(Component* component);
@@ -52,6 +52,11 @@ class ScreenInteractive : public Screen {
   std::string reset_cursor_position;
 
   std::atomic<bool> quit_ = false;
+
+  int cursor_x_ = 0;
+  int cursor_y_ = 0;
+
+  bool mouse_captured = false;
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/component/slider.hpp b/include/ftxui/component/slider.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b30d4272a84e648d8089e84a3ba7419ee67c49d
--- /dev/null
+++ b/include/ftxui/component/slider.hpp
@@ -0,0 +1,23 @@
+#ifndef FTXUI_COMPONENT_SLIDER_HPP
+#define FTXUI_COMPONENT_SLIDER_HPP
+
+#include <string>
+#include "ftxui/component/component.hpp"
+
+namespace ftxui {
+// ComponentPtr Slider(std::string label,
+// float* value,
+// float min = 0.f,
+// float max = 100.f,
+// float increment = (max - min) * 0.05f);
+
+template <class T>  // T = {int, float}
+ComponentPtr Slider(std::wstring label, T* value, T min, T max, T increment);
+
+}  // namespace ftxui
+
+#endif /* end of include guard: FTXUI_COMPONENT_SLIDER_HPP */
+
+// Copyright 2020 Arthur Sonzogni. All rights reserved.
+// Use of this source code is governed by the MIT license that can be found in
+// the LICENSE file.
diff --git a/include/ftxui/component/toggle.hpp b/include/ftxui/component/toggle.hpp
index bbe095c7d1e5df462f1e54719095d9851ff7c71d..bbdd1f1d1dc019c26d57aac863a89bb5af15399c 100644
--- a/include/ftxui/component/toggle.hpp
+++ b/include/ftxui/component/toggle.hpp
@@ -1,12 +1,15 @@
 #ifndef FTXUI_COMPONENT_TOGGLE_H_
 #define FTXUI_COMPONENT_TOGGLE_H_
 
-#include <functional>
 #include <string>
+#include <vector>
 
 #include "ftxui/component/component.hpp"
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/screen/box.hpp"
 
 namespace ftxui {
+struct Event;
 
 /// @brief An horizontal list of elements. The user can navigate through them.
 /// @ingroup component
@@ -16,12 +19,14 @@ class Toggle : public Component {
   ~Toggle() override = default;
 
   // State.
-  int selected = 0;
   std::vector<std::wstring> entries = {L"On", L"Off"};
+  int selected = 0;
+  int focused = 0;
 
+  Decorator normal_style = dim;
   Decorator focused_style = inverted;
   Decorator selected_style = bold;
-  Decorator normal_style = dim;
+  Decorator selected_focused_style = focused_style | selected_style;
 
   // Callback.
   std::function<void()> on_change = []() {};
@@ -30,6 +35,10 @@ class Toggle : public Component {
   // Component implementation.
   Element Render() override;
   bool OnEvent(Event) override;
+
+ private:
+  bool OnMouseEvent(Event event);
+  std::vector<Box> boxes_;
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/dom/elements.hpp b/include/ftxui/dom/elements.hpp
index 30191635ff648b07b3c3ecde396b0005444f155a..073b78338dce20aadf3e27b17bc901d353b3bc29 100644
--- a/include/ftxui/dom/elements.hpp
+++ b/include/ftxui/dom/elements.hpp
@@ -5,6 +5,7 @@
 #include <memory>
 
 #include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
 #include "ftxui/screen/color.hpp"
 #include "ftxui/screen/screen.hpp"
 
@@ -77,6 +78,9 @@ enum Direction { WIDTH, HEIGHT };
 enum Constraint { LESS_THAN, EQUAL, GREATER_THAN };
 Decorator size(Direction, Constraint, int value);
 
+// --
+Decorator reflect(Box& box);
+
 // --- Frame ---
 // A frame is a scrollable area. The internal area is potentially larger than
 // the external one. The internal area is scrolled in order to make visible the
diff --git a/include/ftxui/dom/node.hpp b/include/ftxui/dom/node.hpp
index 7998da6b66e1021953d82237e17d6e3e82b47d7e..3ca51394e8e392409b3db2b0e4c992736b4b6e1d 100644
--- a/include/ftxui/dom/node.hpp
+++ b/include/ftxui/dom/node.hpp
@@ -1,16 +1,18 @@
 #ifndef FTXUI_DOM_NODE_HPP
 #define FTXUI_DOM_NODE_HPP
 
-#include <memory>
-#include <vector>
+#include <memory>  // for shared_ptr
+#include <vector>  // for vector
 
-#include "ftxui/dom/requirement.hpp"
-#include "ftxui/screen/box.hpp"
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
 #include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
 class Node;
+class Screen;
+
 using Element = std::shared_ptr<Node>;
 using Elements = std::vector<std::shared_ptr<Node>>;
 
diff --git a/include/ftxui/dom/take_any_args.hpp b/include/ftxui/dom/take_any_args.hpp
index fecee2389b355efbdb44c2f71fd411288e385217..3adf2237b3cd17f782b77c116a430a2e549a4e45 100644
--- a/include/ftxui/dom/take_any_args.hpp
+++ b/include/ftxui/dom/take_any_args.hpp
@@ -1,3 +1,4 @@
+// IWYU pragma: private, include "ftxui/dom/elements.hpp"
 #include <type_traits>
 
 template <class T>
diff --git a/include/ftxui/screen/box.hpp b/include/ftxui/screen/box.hpp
index 3a643027a5559728d375fe5c3c86fc2d43acf5a6..719e1bd5df5470a52af3e1d38bbaa73ed334a3eb 100644
--- a/include/ftxui/screen/box.hpp
+++ b/include/ftxui/screen/box.hpp
@@ -10,6 +10,7 @@ struct Box {
   int y_max;
 
   static Box Intersection(Box a, Box b);
+  bool Contain(int x, int y);
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/screen/color.hpp b/include/ftxui/screen/color.hpp
index 6bb0c19b738a4d00a5461a6a7863ae73d4cec6cf..e8edbcb82c8b9c5fdac9a9741f6946951e48e0cf 100644
--- a/include/ftxui/screen/color.hpp
+++ b/include/ftxui/screen/color.hpp
@@ -1,8 +1,8 @@
 #ifndef FTXUI_SCREEN_COLOR
 #define FTXUI_SCREEN_COLOR
 
-#include <cstdint>
-#include <string>
+#include <stdint.h>  // for uint8_t
+#include <string>    // for wstring
 
 #ifdef RGB
 // Workaround for wingdi.h (via Windows.h) defining macros that break things.
diff --git a/include/ftxui/screen/color_info.hpp b/include/ftxui/screen/color_info.hpp
index b3c64ca418f7915f7e5640c7ce758a94f108e4d1..5a35fc5bf728c1edf4e5cc0dee9e9fee97f2210b 100644
--- a/include/ftxui/screen/color_info.hpp
+++ b/include/ftxui/screen/color_info.hpp
@@ -1,6 +1,7 @@
 #ifndef FTXUI_SCREEN_COLOR_INFO_HPP
 #define FTXUI_SCREEN_COLOR_INFO_HPP
 
+#include <stdint.h>
 #include <ftxui/screen/color.hpp>
 
 namespace ftxui {
diff --git a/iwyu.imp b/iwyu.imp
new file mode 100644
index 0000000000000000000000000000000000000000..feaf961bd2c25e4d2fb95093125117f35dd317c3
--- /dev/null
+++ b/iwyu.imp
@@ -0,0 +1,8 @@
+[
+  { symbol: [ "VMIN", private, "<termios.h>", public ] },
+  { symbol: [ "VTIME", private, "<termios.h>", public ] },
+  { symbol: [ "ECHO", private, "<termios.h>", public ] },
+  { symbol: [ "ICANON", private, "<termios.h>", public ] },
+  { symbol: [ "termios", private, "<termios.h>", public ] },
+  { symbol: [ "TCSANOW", private, "<termios.h>", public ] },
+]
diff --git a/src/ftxui/component/button.cpp b/src/ftxui/component/button.cpp
index 581298ec77c872e038ecff576a000dae0b569838..357b5945ebb4458bae96af4a33cfe0eb3e009fe2 100644
--- a/src/ftxui/component/button.cpp
+++ b/src/ftxui/component/button.cpp
@@ -1,17 +1,35 @@
-#include "ftxui/component/button.hpp"
+#include <functional>  // for function
+#include <memory>      // for shared_ptr
 
-#include <functional>
+#include "ftxui/component/button.hpp"
+#include "ftxui/component/captured_mouse.hpp"  // for CapturedMouse
+#include "ftxui/component/event.hpp"           // for Event, Event::Return
+#include "ftxui/component/mouse.hpp"  // for Mouse, Mouse::Left, Mouse::Pressed
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
 
 namespace ftxui {
 
 Element Button::Render() {
-  if (Focused())
-    return text(label) | border | inverted;
-  else
-    return text(label) | border;
+  auto style = Focused() ? inverted : nothing;
+  return text(label) | border | style | reflect(box_);
 }
 
 bool Button::OnEvent(Event event) {
+  if (event.is_mouse() && box_.Contain(event.mouse().x, event.mouse().y)) {
+    if (!CaptureMouse(event))
+      return false;
+
+    TakeFocus();
+
+    if (event.mouse().button == Mouse::Left &&
+        event.mouse().motion == Mouse::Pressed) {
+      on_click();
+      return true;
+    }
+
+    return false;
+  }
+
   if (event == Event::Return) {
     on_click();
     return true;
diff --git a/src/ftxui/component/checkbox.cpp b/src/ftxui/component/checkbox.cpp
index 9f9cfd96b83aaea2d0a2853e575974c204d50ef7..a7382d87e2a5244d418c8b9d59d07e4a70838e22 100644
--- a/src/ftxui/component/checkbox.cpp
+++ b/src/ftxui/component/checkbox.cpp
@@ -1,6 +1,11 @@
-#include "ftxui/component/checkbox.hpp"
+#include <functional>  // for function
+#include <memory>      // for shared_ptr
 
-#include <functional>
+#include "ftxui/component/captured_mouse.hpp"  // for CapturedMouse
+#include "ftxui/component/checkbox.hpp"
+#include "ftxui/component/event.hpp"  // for Event, Event::Return
+#include "ftxui/component/mouse.hpp"  // for Mouse, Mouse::Left, Mouse::Pressed
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
 
 namespace ftxui {
 
@@ -9,10 +14,14 @@ Element CheckBox::Render() {
   auto style = is_focused ? focused_style : unfocused_style;
   auto focus_management = is_focused ? focus : state ? select : nothing;
   return hbox(text(state ? checked : unchecked),
-              text(label) | style | focus_management);
+              text(label) | style | focus_management) |
+         reflect(box_);
 }
 
 bool CheckBox::OnEvent(Event event) {
+  if (event.is_mouse())
+    return OnMouseEvent(event);
+
   if (event == Event::Character(' ') || event == Event::Return) {
     state = !state;
     on_change();
@@ -21,6 +30,24 @@ bool CheckBox::OnEvent(Event event) {
   return false;
 }
 
+bool CheckBox::OnMouseEvent(Event event) {
+    if (!CaptureMouse(event))
+    return false;
+  if (!box_.Contain(event.mouse().x, event.mouse().y))
+    return false;
+
+  TakeFocus();
+
+  if (event.mouse().button == Mouse::Left &&
+      event.mouse().motion == Mouse::Pressed) {
+    state = !state;
+    on_change();
+    return true;
+  }
+
+  return false;
+}
+
 }  // namespace ftxui
 
 // Copyright 2020 Arthur Sonzogni. All rights reserved.
diff --git a/src/ftxui/component/component.cpp b/src/ftxui/component/component.cpp
index d89de450e496a84640ea75d72edb25296738354b..875d759f8f96be1b4bea2147f146ca4aa81f365f 100644
--- a/src/ftxui/component/component.cpp
+++ b/src/ftxui/component/component.cpp
@@ -1,11 +1,20 @@
 #include "ftxui/component/component.hpp"
 
-#include <assert.h>
-
 #include <algorithm>
 
+#include "ftxui/component/captured_mouse.hpp"
+#include "ftxui/component/event.hpp"
+#include "ftxui/component/screen_interactive.hpp"
+
 namespace ftxui {
 
+namespace {
+class CaptureMouseImpl : public CapturedMouseInterface {
+ public:
+  ~CaptureMouseImpl() override {}
+};
+}
+
 Component::~Component() {
   Detach();
 }
@@ -97,6 +106,16 @@ void Component::TakeFocus() {
   }
 }
 
+/// @brief Take the CapturedMouse if available. There is only one component of
+/// them. It represents a component taking priority over others.
+/// @argument event
+/// @ingroup component
+CapturedMouse Component::CaptureMouse(const Event& event) {
+  if (!event.screen_)
+    return std::make_unique<CaptureMouseImpl>();
+  return event.screen_->CaptureMouse();
+}
+
 /// @brief Detach this children from its parent.
 /// @see Attach
 /// @see Detach
diff --git a/src/ftxui/component/container.cpp b/src/ftxui/component/container.cpp
index 4b55bcd8e7815eef060f42173f870810bd5e102f..7c01a1d02b28092375a1db5d6b08efb41910ac8c 100644
--- a/src/ftxui/component/container.cpp
+++ b/src/ftxui/component/container.cpp
@@ -1,6 +1,8 @@
 #include "ftxui/component/container.hpp"
 
+#include <stddef.h>
 #include <algorithm>
+#include <vector>
 
 namespace ftxui {
 
@@ -30,6 +32,9 @@ Container Container::Tab(int* selector) {
 }
 
 bool Container::OnEvent(Event event) {
+  if (event.is_mouse())
+    return OnMouseEvent(event);
+
   if (!Focused())
     return false;
 
@@ -115,6 +120,17 @@ Element Container::TabRender() {
   return text(L"Empty container");
 }
 
+bool Container::OnMouseEvent(Event event) {
+  if (selector_)
+    return ActiveChild()->OnEvent(event);
+
+  for (Component* child : children_) {
+    if (child->OnEvent(event))
+      return true;
+  }
+  return false;
+}
+
 }  // namespace ftxui
 
 // Copyright 2020 Arthur Sonzogni. All rights reserved.
diff --git a/src/ftxui/component/container_test.cpp b/src/ftxui/component/container_test.cpp
index 86f36aec83fa7ac6f405be2b04abf1e377d3bb9d..da47638ce89859d4011a402e92af6ca212b2d58b 100644
--- a/src/ftxui/component/container_test.cpp
+++ b/src/ftxui/component/container_test.cpp
@@ -1,6 +1,10 @@
-#include "ftxui/component/container.hpp"
+#include <gtest/gtest-message.h>    // for Message
+#include <gtest/gtest-test-part.h>  // for TestPartResult, SuiteApiResolver
+#include <memory>                   // for allocator
 
-#include "gtest/gtest.h"
+#include "ftxui/component/container.hpp"
+#include "ftxui/screen/box.hpp"     // for ftxui
+#include "gtest/gtest_pred_impl.h"  // for AssertionResult, EXPECT_EQ, EXPEC...
 
 using namespace ftxui;
 
diff --git a/src/ftxui/component/event.cpp b/src/ftxui/component/event.cpp
index b8c6d7a40427c40ee1f87f7f44920be80f49af18..6987368fa13443b5c292e0087e54e196806fd0c3 100644
--- a/src/ftxui/component/event.cpp
+++ b/src/ftxui/component/event.cpp
@@ -1,16 +1,16 @@
 #include "ftxui/component/event.hpp"
 
-#include <iostream>
+#include "ftxui/component/mouse.hpp"
 #include "ftxui/screen/string.hpp"
 
 namespace ftxui {
 
 // static
-Event Event::Character(const std::string& input) {
+Event Event::Character(std::string input) {
   Event event;
-  event.input_ = input;
-  event.is_character_ = true;
   event.character_ = to_wstring(input)[0];
+  event.input_ = std::move(input);
+  event.type_ = Type::Character;
   return event;
 }
 
@@ -23,15 +23,34 @@ Event Event::Character(char c) {
 Event Event::Character(wchar_t c) {
   Event event;
   event.input_ = {(char)c};
-  event.is_character_ = true;
+  event.type_ = Type::Character;
   event.character_ = c;
   return event;
 }
 
 // static
-Event Event::Special(const std::string& input) {
+Event Event::Mouse(std::string input, struct Mouse mouse) {
+  Event event;
+  event.input_ = std::move(input);
+  event.type_ = Type::Mouse;
+  event.mouse_ = mouse;
+  return event;
+}
+
+// static
+Event Event::Special(std::string input) {
+  Event event;
+  event.input_ = std::move(input);
+  return event;
+}
+
+// static
+Event Event::CursorReporting(std::string input, int x, int y) {
   Event event;
   event.input_ = std::move(input);
+  event.type_ = Type::CursorReporting;
+  event.cursor_.x = x;
+  event.cursor_.y = y;
   return event;
 }
 
diff --git a/src/ftxui/component/input.cpp b/src/ftxui/component/input.cpp
index 0223c941ea7f4262f70d18e120bca14a0de320f9..5097bbda62140512c6a2b78ab70124c4b94639ab 100644
--- a/src/ftxui/component/input.cpp
+++ b/src/ftxui/component/input.cpp
@@ -1,8 +1,11 @@
 #include "ftxui/component/input.hpp"
 
 #include <algorithm>
+#include <memory>
 
-#include "ftxui/screen/string.hpp"
+#include "ftxui/component/captured_mouse.hpp"
+#include "ftxui/component/mouse.hpp"
+#include "ftxui/component/screen_interactive.hpp"
 
 namespace ftxui {
 
@@ -15,14 +18,15 @@ Element Input::Render() {
   // Placeholder.
   if (content.size() == 0) {
     if (is_focused)
-      return text(placeholder) | focus | dim | inverted | main_decorator;
+      return text(placeholder) | focus | dim | inverted | main_decorator |
+             reflect(input_box_);
     else
-      return text(placeholder) | dim | main_decorator;
+      return text(placeholder) | dim | main_decorator | reflect(input_box_);
   }
 
   // Not focused.
   if (!is_focused)
-    return text(content) | main_decorator;
+    return text(content) | main_decorator | reflect(input_box_);
 
   std::wstring part_before_cursor = content.substr(0, cursor_position);
   std::wstring part_at_cursor = cursor_position < (int)content.size()
@@ -37,13 +41,18 @@ Element Input::Render() {
   return
     hbox(
       text(part_before_cursor),
-      text(part_at_cursor) | underlined | focused,
+      text(part_at_cursor) | underlined | focused | reflect(cursor_box_),
       text(part_after_cursor)
-    ) | flex | inverted | frame | main_decorator;
-  // clang-format off
+    ) | flex | inverted | frame | main_decorator | reflect(input_box_);
+  // clang-format on
 }
+
 bool Input::OnEvent(Event event) {
   cursor_position = std::max(0, std::min<int>(content.size(), cursor_position));
+
+  if (event.is_mouse())
+    return OnMouseEvent(event);
+
   std::wstring c;
 
   // Backspace.
@@ -105,6 +114,28 @@ bool Input::OnEvent(Event event) {
   return false;
 }
 
+bool Input::OnMouseEvent(Event event) {
+  if (!CaptureMouse(event))
+    return false;
+  if (!input_box_.Contain(event.mouse().x, event.mouse().y))
+    return false;
+
+  TakeFocus();
+
+  if (event.mouse().button == Mouse::Left &&
+      event.mouse().motion == Mouse::Pressed) {
+    int new_cursor_position =
+        cursor_position + event.mouse().x - cursor_box_.x_min;
+    new_cursor_position =
+        std::max(0, std::min<int>(content.size(), new_cursor_position));
+    if (cursor_position != new_cursor_position) {
+      cursor_position = new_cursor_position;
+      on_change();
+    }
+  }
+  return true;
+}
+
 }  // namespace ftxui
 
 // Copyright 2020 Arthur Sonzogni. All rights reserved.
diff --git a/src/ftxui/component/input_test.cpp b/src/ftxui/component/input_test.cpp
index 4bfc6b95fc3e4952fa512d53d4dd3262e476ce77..7f4fa50327b1f6b97f52a4efef851b1d6a3ce97a 100644
--- a/src/ftxui/component/input_test.cpp
+++ b/src/ftxui/component/input_test.cpp
@@ -1,4 +1,5 @@
 #include "ftxui/component/input.hpp"
+#include "ftxui/component/event.hpp"
 
 #include "gtest/gtest.h"
 
diff --git a/src/ftxui/component/menu.cpp b/src/ftxui/component/menu.cpp
index 12b5ee3470b9d2d0fce12eca4e6803e33334978a..90b19878286eadb8525e32f081a30d9c4b75aa4c 100644
--- a/src/ftxui/component/menu.cpp
+++ b/src/ftxui/component/menu.cpp
@@ -1,25 +1,43 @@
 #include "ftxui/component/menu.hpp"
 
+#include <stddef.h>
 #include <algorithm>
-#include <iostream>
+#include <memory>
+#include <utility>
+
+#include "ftxui/component/captured_mouse.hpp"
+#include "ftxui/component/mouse.hpp"
+#include "ftxui/component/screen_interactive.hpp"
 
 namespace ftxui {
 
 Element Menu::Render() {
-  std::vector<Element> elements;
-  bool is_focused = Focused();
+  Elements elements;
+  bool is_menu_focused = Focused();
+  boxes_.resize(entries.size());
   for (size_t i = 0; i < entries.size(); ++i) {
-    auto style = (selected != int(i))
-                     ? normal_style
-                     : is_focused ? focused_style : selected_style;
-    auto focused = (selected != int(i)) ? nothing : is_focused ? focus : select;
-    auto icon = (selected != int(i)) ? L"  " : L"> ";
-    elements.push_back(text(icon + entries[i]) | style | focused);
+    bool is_focused = (focused == int(i)) && is_menu_focused;
+    bool is_selected = (selected == int(i));
+
+    auto style = is_selected
+                     ? (is_focused ? selected_focused_style : selected_style)
+                     : (is_focused ? focused_style : normal_style);
+    auto focus_management = !is_selected      ? nothing
+                            : is_menu_focused ? focus
+                                              : select;
+    auto icon = is_selected ? L"> " : L"  ";
+    elements.push_back(text(icon + entries[i]) | style | focus_management |
+                       reflect(boxes_[i]));
   }
   return vbox(std::move(elements));
 }
 
 bool Menu::OnEvent(Event event) {
+  if (!CaptureMouse(event))
+    return false;
+  if (event.is_mouse())
+    return OnMouseEvent(event);
+
   if (!Focused())
     return false;
 
@@ -36,6 +54,7 @@ bool Menu::OnEvent(Event event) {
   selected = std::max(0, std::min(int(entries.size()) - 1, selected));
 
   if (selected != old_selected) {
+    focused = selected;
     on_change();
     return true;
   }
@@ -48,6 +67,27 @@ bool Menu::OnEvent(Event event) {
   return false;
 }
 
+bool Menu::OnMouseEvent(Event event) {
+  if (!CaptureMouse(event))
+    return false;
+  for (int i = 0; i < boxes_.size(); ++i) {
+    if (!boxes_[i].Contain(event.mouse().x, event.mouse().y))
+      continue;
+
+    TakeFocus();
+    focused = i;
+    if (event.mouse().button == Mouse::Left &&
+        event.mouse().motion == Mouse::Released) {
+      if (selected != i) {
+        selected = i;
+        on_change();
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
 }  // namespace ftxui
 
 // Copyright 2020 Arthur Sonzogni. All rights reserved.
diff --git a/src/ftxui/component/radiobox.cpp b/src/ftxui/component/radiobox.cpp
index ff7d169f82747cb33fa6e3ee1201eecebac74390..4d6c00a20aef71d6c5eeabc199488899dacafefa 100644
--- a/src/ftxui/component/radiobox.cpp
+++ b/src/ftxui/component/radiobox.cpp
@@ -1,27 +1,41 @@
 #include "ftxui/component/radiobox.hpp"
 
+#include <stddef.h>
 #include <algorithm>
 #include <functional>
+#include <memory>
+#include <utility>
+
+#include "ftxui/component/captured_mouse.hpp"
+#include "ftxui/component/mouse.hpp"
+#include "ftxui/component/screen_interactive.hpp"
 
 namespace ftxui {
 
 Element RadioBox::Render() {
   std::vector<Element> elements;
   bool is_focused = Focused();
+  boxes_.resize(entries.size());
   for (size_t i = 0; i < entries.size(); ++i) {
     auto style =
         (focused == int(i) && is_focused) ? focused_style : unfocused_style;
-    auto focus_management =
-        (focused != int(i)) ? nothing : is_focused ? focus : select;
+    auto focus_management = (focused != int(i)) ? nothing
+                            : is_focused        ? focus
+                                                : select;
 
     const std::wstring& symbol = selected == int(i) ? checked : unchecked;
     elements.push_back(hbox(text(symbol), text(entries[i]) | style) |
-                       focus_management);
+                       focus_management | reflect(boxes_[i]));
   }
   return vbox(std::move(elements));
 }
 
 bool RadioBox::OnEvent(Event event) {
+  if (!CaptureMouse(event))
+    return false;
+  if (event.is_mouse())
+    return OnMouseEvent(event);
+
   if (!Focused())
     return false;
 
@@ -50,6 +64,30 @@ bool RadioBox::OnEvent(Event event) {
   return false;
 }
 
+bool RadioBox::OnMouseEvent(Event event) {
+  if (!CaptureMouse(event))
+    return false;
+  for (int i = 0; i < boxes_.size(); ++i) {
+    if (!boxes_[i].Contain(event.mouse().x, event.mouse().y))
+      continue;
+
+    focused = i;
+    TakeFocus();
+
+    if (event.mouse().button == Mouse::Left &&
+        event.mouse().motion == Mouse::Pressed) {
+      cursor_position = i;
+      TakeFocus();
+      if (selected != i) {
+        selected = i;
+        on_change();
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
 }  // namespace ftxui
 
 // Copyright 2020 Arthur Sonzogni. All rights reserved.
diff --git a/src/ftxui/component/radiobox_test.cpp b/src/ftxui/component/radiobox_test.cpp
index 8fd5c2d36afbb326afe244f9bfdebf7b36d549f6..845dac0f15e0b7b006dad5ee43ee7bfc6ae56fff 100644
--- a/src/ftxui/component/radiobox_test.cpp
+++ b/src/ftxui/component/radiobox_test.cpp
@@ -1,6 +1,10 @@
-#include "ftxui/component/radiobox.hpp"
+#include <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // for TestPartResult, SuiteApiResolver, TestFactoryImpl
 
-#include "gtest/gtest.h"
+#include "ftxui/component/event.hpp"  // for Event, Event::ArrowDown, Event::ArrowUp, Event::Tab, Event::TabReverse
+#include "ftxui/component/mouse.hpp"  // for ftxui
+#include "ftxui/component/radiobox.hpp"
+#include "gtest/gtest_pred_impl.h"  // for EXPECT_EQ, Test, TEST
 
 using namespace ftxui;
 
diff --git a/src/ftxui/component/receiver_test.cpp b/src/ftxui/component/receiver_test.cpp
index 8d06cc8eb9aeed1bd488040102a136766a29b66f..bd4e1cb63e2cede715b98f9348f875897085d882 100644
--- a/src/ftxui/component/receiver_test.cpp
+++ b/src/ftxui/component/receiver_test.cpp
@@ -1,8 +1,10 @@
-#include "ftxui/component/receiver.hpp"
-
-#include <thread>
+#include <gtest/gtest-message.h>    // for Message
+#include <gtest/gtest-test-part.h>  // for TestPartResult
+#include <thread>                   // for thread
+#include <utility>                  // for move
 
-#include "gtest/gtest.h"
+#include "ftxui/component/receiver.hpp"
+#include "gtest/gtest_pred_impl.h"  // for AssertionResult, Test, EXPECT_EQ
 
 using namespace ftxui;
 
diff --git a/src/ftxui/component/screen_interactive.cpp b/src/ftxui/component/screen_interactive.cpp
index b4f3753b4b51f43b249617b74a9b88ff0f546084..c02dccf76ad0dd4731970e76d302df85b2313ed1 100644
--- a/src/ftxui/component/screen_interactive.cpp
+++ b/src/ftxui/component/screen_interactive.cpp
@@ -1,18 +1,24 @@
 #include "ftxui/component/screen_interactive.hpp"
 
-#include <stdio.h>
-
-#include <algorithm>
-#include <csignal>
-#include <cstdlib>
-#include <iostream>
-#include <stack>
-#include <thread>
-
-#include "ftxui/component/component.hpp"
-#include "ftxui/component/terminal_input_parser.hpp"
-#include "ftxui/screen/string.hpp"
-#include "ftxui/screen/terminal.hpp"
+#include <stdio.h>    // for fileno, stdin
+#include <algorithm>  // for copy, max, min
+#include <csignal>    // for signal, SIGINT
+#include <cstdlib>    // for exit, NULL
+#include <iostream>   // for cout, ostream
+#include <stack>      // for stack
+#include <thread>     // for thread
+#include <utility>    // for move
+#include <vector>     // for vector
+
+#include "ftxui/component/captured_mouse.hpp"         // for CapturedMouse
+#include "ftxui/component/component.hpp"              // for Component
+#include "ftxui/component/event.hpp"                  // for Event
+#include "ftxui/component/mouse.hpp"                  // for Mouse
+#include "ftxui/component/receiver.hpp"               // for ReceiverImpl
+#include "ftxui/component/terminal_input_parser.hpp"  // for TerminalInputPa...
+#include "ftxui/dom/node.hpp"                         // for Node, Render
+#include "ftxui/dom/requirement.hpp"                  // for Requirement
+#include "ftxui/screen/terminal.hpp"                  // for Terminal::Dimen...
 
 #if defined(_WIN32)
 #define DEFINE_CONSOLEV2_PROPERTIES
@@ -25,8 +31,9 @@
 #error Must be compiled in UNICODE mode
 #endif
 #else
-#include <termios.h>
-#include <unistd.h>
+#include <sys/select.h>  // for select, FD_ISSET
+#include <termios.h>     // for tcsetattr, tcge...
+#include <unistd.h>      // for STDIN_FILENO, read
 #endif
 
 // Quick exit is missing in standard CLang headers
@@ -40,15 +47,14 @@ namespace {
 
 void Flush() {
   // Emscripten doesn't implement flush. We interpret zero as flush.
-  std::cout << std::flush << (char)0;
+  std::cout << '\0' << std::flush;
 }
 
 constexpr int timeout_milliseconds = 20;
 constexpr int timeout_microseconds = timeout_milliseconds * 1000;
 #if defined(_WIN32)
 
-void EventListener(std::atomic<bool>* quit,
-                        Sender<Event> out) {
+void EventListener(std::atomic<bool>* quit, Sender<Event> out) {
   auto console = GetStdHandle(STD_INPUT_HANDLE);
   auto parser = TerminalInputParser(out->Clone());
   while (!*quit) {
@@ -68,8 +74,7 @@ void EventListener(std::atomic<bool>* quit,
 
     std::vector<INPUT_RECORD> records{number_of_events};
     DWORD number_of_events_read = 0;
-    ReadConsoleInput(console, records.data(),
-                     (DWORD)records.size(),
+    ReadConsoleInput(console, records.data(), (DWORD)records.size(),
                      &number_of_events_read);
     records.resize(number_of_events_read);
 
@@ -114,7 +119,7 @@ void EventListener(std::atomic<bool>* quit, Sender<Event> out) {
 }
 
 #else
-#include <sys/time.h>
+#include <sys/time.h>  // for timeval
 
 int CheckStdinReady(int usec_timeout) {
   timeval tv = {0, usec_timeout};
@@ -146,14 +151,53 @@ void EventListener(std::atomic<bool>* quit, Sender<Event> out) {
 
 #endif
 
-static const char* HIDE_CURSOR = "\x1B[?25l";
-static const char* SHOW_CURSOR = "\x1B[?25h";
+const std::string CSI = "\x1b[";
+
+// DEC: Digital Equipment Corporation
+enum class DECMode {
+  kLineWrap = 7,
+  kMouseX10 = 9,
+  kCursor = 25,
+  kMouseVt200 = 1000,
+  kMouseAnyEvent = 1003,
+  kMouseUtf8 = 1005,
+  kMouseSgrExtMode = 1006,
+  kMouseUrxvtMode = 1015,
+  kMouseSgrPixelsMode = 1016,
+  kAlternateScreen = 1049,
+};
+
+// Device Status Report (DSR) {
+enum class DSRMode {
+  kCursor = 6,
+};
+
+const std::string Serialize(std::vector<DECMode> parameters) {
+  bool first = true;
+  std::string out;
+  for (DECMode parameter : parameters) {
+    if (!first)
+      out += ";";
+    out += std::to_string(int(parameter));
+    first = false;
+  }
+  return out;
+}
+
+// DEC Private Mode Set (DECSET)
+const std::string Set(std::vector<DECMode> parameters) {
+  return CSI + "?" + Serialize(parameters) + "h";
+}
 
-static const char* DISABLE_LINE_WRAP = "\x1B[7l";
-static const char* ENABLE_LINE_WRAP = "\x1B[7h";
+// DEC Private Mode Reset (DECRST)
+const std::string Reset(std::vector<DECMode> parameters) {
+  return CSI + "?" + Serialize(parameters) + "l";
+}
 
-static const char* USE_ALTERNATIVE_SCREEN = "\x1B[?1049h";
-static const char* USE_NORMAL_SCREEN = "\x1B[?1049l";
+// Device Status Report (DSR)
+const std::string DeviceStatusReport(DSRMode ps) {
+  return CSI + std::to_string(int(ps)) + "n";
+}
 
 using SignalHandler = void(int);
 std::stack<std::function<void()>> on_exit_functions;
@@ -177,6 +221,15 @@ void OnResize(int /* signal */) {
   on_resize();
 }
 
+class CapturedMouseImpl : public CapturedMouseInterface {
+ public:
+  CapturedMouseImpl(std::function<void(void)> callback) : callback_(callback) {}
+  ~CapturedMouseImpl() override { callback_(); }
+
+ private:
+  std::function<void(void)> callback_;
+};
+
 }  // namespace
 
 ScreenInteractive::ScreenInteractive(int dimx,
@@ -217,6 +270,14 @@ void ScreenInteractive::PostEvent(Event event) {
     event_sender_->Send(event);
 }
 
+CapturedMouse ScreenInteractive::CaptureMouse() {
+  if (mouse_captured)
+    return nullptr;
+  mouse_captured = true;
+  return std::make_unique<CapturedMouseImpl>(
+      [this] { mouse_captured = false; });
+}
+
 void ScreenInteractive::Loop(Component* component) {
   // Install a SIGINT handler and restore the old handler on exit.
   auto old_sigint_handler = std::signal(SIGINT, OnExit);
@@ -274,23 +335,48 @@ void ScreenInteractive::Loop(Component* component) {
   install_signal_handler(SIGWINCH, OnResize);
 #endif
 
+  // Commit state:
+  auto flush = [&] {
+    Flush();
+    on_exit_functions.push([] { Flush(); });
+  };
+
+  auto enable = [&](std::vector<DECMode> parameters) {
+    std::cout << Set(parameters);
+    on_exit_functions.push([=] { std::cout << Reset(parameters); });
+  };
+
+  auto disable = [&](std::vector<DECMode> parameters) {
+    std::cout << Reset(parameters);
+    on_exit_functions.push([=] { std::cout << Set(parameters); });
+  };
+
+  flush();
+
   if (use_alternative_screen_) {
-    std::cout << USE_ALTERNATIVE_SCREEN;
-    on_exit_functions.push([] { std::cout << USE_NORMAL_SCREEN; });
+    enable({
+        DECMode::kAlternateScreen,
+    });
   }
 
-  // Hide the cursor and show it at exit.
-  std::cout << HIDE_CURSOR;
-  std::cout << DISABLE_LINE_WRAP;
-  Flush();
-  on_exit_functions.push([&] {
-    std::cout << reset_cursor_position;
-    std::cout << SHOW_CURSOR;
-    std::cout << ENABLE_LINE_WRAP;
-    std::cout << std::endl;
-    Flush();
+  // On exit, reset cursor one line after the current drawing.
+  on_exit_functions.push(
+      [=] { std::cout << reset_cursor_position << std::endl; });
+
+  disable({
+      DECMode::kCursor,
+      DECMode::kLineWrap,
+  });
+
+  enable({
+      // DECMode::kMouseVt200,
+      DECMode::kMouseAnyEvent,
+      DECMode::kMouseUtf8,
+      DECMode::kMouseSgrExtMode,
   });
 
+  flush();
+
   auto event_listener =
       std::thread(&EventListener, &quit_, event_receiver_->MakeSender());
 
@@ -298,14 +384,33 @@ void ScreenInteractive::Loop(Component* component) {
   while (!quit_) {
     if (!event_receiver_->HasPending()) {
       std::cout << reset_cursor_position << ResetPosition();
+      static int i = -2;
+      if (i % 10 == 0)
+        std::cout << DeviceStatusReport(DSRMode::kCursor);
+      ++i;
       Draw(component);
       std::cout << ToString() << set_cursor_position;
       Flush();
       Clear();
     }
+
     Event event;
-    if (event_receiver_->Receive(&event))
-      component->OnEvent(event);
+    if (!event_receiver_->Receive(&event))
+      break;
+
+    if (event.is_cursor_reporting()) {
+      cursor_x_ = event.cursor_x();
+      cursor_y_ = event.cursor_y();
+      continue;
+    }
+
+    if (event.is_mouse()) {
+      event.mouse().x -= cursor_x_;
+      event.mouse().y -= cursor_y_;
+    }
+
+    event.screen_ = this;
+    component->OnEvent(event);
   }
 
   event_listener.join();
diff --git a/src/ftxui/component/slider.cpp b/src/ftxui/component/slider.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..122e523b1b45972c3ae69c0d87c1f2d96b8fd623
--- /dev/null
+++ b/src/ftxui/component/slider.cpp
@@ -0,0 +1,119 @@
+#include "ftxui/component/slider.hpp"
+
+#include <memory>
+#include <utility>
+
+#include "ftxui/component/captured_mouse.hpp"
+#include "ftxui/component/mouse.hpp"
+#include "ftxui/component/screen_interactive.hpp"
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
+
+namespace ftxui {
+
+template <class T>
+class SliderImpl : public Component {
+ public:
+  SliderImpl(std::wstring label, T* value, T min, T max, T increment)
+      : label_(label),
+        value_(value),
+        min_(min),
+        max_(max),
+        increment_(increment) {}
+
+  Element Render() {
+    auto gauge_color =
+        Focused() ? color(Color::GrayLight) : color(Color::GrayDark);
+    float percent = float(*value_ - min_) / float(max_ - min_);
+    return hbox({
+               text(label_) | dim | vcenter,
+               hbox({
+                   text(L"["),
+                   gauge(percent) | underlined | xflex | reflect(gauge_box_),
+                   text(L"]"),
+               }) | xflex,
+           }) |
+           gauge_color | xflex | reflect(box_);
+  }
+
+  bool OnEvent(Event event) final {
+    if (event.is_mouse())
+      return OnMouseEvent(event);
+
+    if (event == Event::ArrowLeft || event == Event::Character('h')) {
+      *value_ -= increment_;
+      *value_ = std::max(*value_, min_);
+      return true;
+    }
+
+    if (event == Event::ArrowRight || event == Event::Character('l')) {
+      *value_ += increment_;
+      *value_ = std::min(*value_, max_);
+      return true;
+    }
+
+    return Component::OnEvent(event);
+  }
+
+  bool OnMouseEvent(Event event) {
+    if (captured_mouse_ && event.mouse().motion == Mouse::Released) {
+      captured_mouse_ = nullptr;
+      return true;
+    }
+
+    if (box_.Contain(event.mouse().x, event.mouse().y) &&
+        CaptureMouse(event)) {
+      TakeFocus();
+    }
+
+    if (event.mouse().button == Mouse::Left &&
+        event.mouse().motion == Mouse::Pressed &&
+        gauge_box_.Contain(event.mouse().x, event.mouse().y) &&
+        !captured_mouse_) {
+      captured_mouse_ = CaptureMouse(event);
+    }
+
+    if (captured_mouse_) {
+      *value_ = min_ + (event.mouse().x - gauge_box_.x_min) * (max_ - min_) /
+                           (gauge_box_.x_max - gauge_box_.x_min);
+      *value_ = std::max(min_, std::min(max_, *value_));
+      return true;
+    }
+    return false;
+  }
+
+ private:
+  std::wstring label_;
+  T* value_;
+  T min_;
+  T max_;
+  T increment_ = 1;
+  Box box_;
+  Box gauge_box_;
+  CapturedMouse captured_mouse_;
+};
+
+template <class T>
+ComponentPtr Slider(std::wstring label, T* value, T min, T max, T increment) {
+  return std::make_unique<SliderImpl<T>>(std::move(label), value, min, max,
+                                         increment);
+}
+
+template ComponentPtr Slider(std::wstring label,
+                             int* value,
+                             int min,
+                             int max,
+                             int increment);
+
+template ComponentPtr Slider(std::wstring label,
+                             float* value,
+                             float min,
+                             float max,
+                             float increment);
+
+}  // namespace ftxui
+
+// Copyright 2020 Arthur Sonzogni. All rights reserved.
+// Use of this source code is governed by the MIT license that can be found in
+// the LICENSE file.
diff --git a/src/ftxui/component/terminal_input_parser.cpp b/src/ftxui/component/terminal_input_parser.cpp
index 78e0fdda86b5cb7a8332e1c3b2c01d4423d10276..acab8e4b6256d38b93b1fd903fa26f57ac88cad2 100644
--- a/src/ftxui/component/terminal_input_parser.cpp
+++ b/src/ftxui/component/terminal_input_parser.cpp
@@ -1,5 +1,8 @@
 #include "ftxui/component/terminal_input_parser.hpp"
 
+#include <utility>
+#include "ftxui/component/event.hpp"
+
 namespace ftxui {
 
 TerminalInputParser::TerminalInputParser(Sender<Event> out)
@@ -30,8 +33,8 @@ bool TerminalInputParser::Eat() {
   return position_ < (int)pending_.size();
 }
 
-void TerminalInputParser::Send(TerminalInputParser::Type type) {
-  switch (type) {
+void TerminalInputParser::Send(TerminalInputParser::Output output) {
+  switch (output.type) {
     case UNCOMPLETED:
       return;
 
@@ -48,10 +51,22 @@ void TerminalInputParser::Send(TerminalInputParser::Type type) {
       out_->Send(Event::Special(std::move(pending_)));
       pending_.clear();
       return;
+
+    case MOUSE:
+      out_->Send(Event::Mouse(std::move(pending_), output.mouse));
+      pending_.clear();
+      return;
+
+    case CURSOR_REPORTING:
+      out_->Send(Event::CursorReporting(std::move(pending_), output.cursor.x,
+                                        output.cursor.y));
+      pending_.clear();
+      return;
   }
+  // NOT_REACHED().
 }
 
-TerminalInputParser::Type TerminalInputParser::Parse() {
+TerminalInputParser::Output TerminalInputParser::Parse() {
   if (!Eat())
     return UNCOMPLETED;
 
@@ -75,7 +90,7 @@ TerminalInputParser::Type TerminalInputParser::Parse() {
   return ParseUTF8();
 }
 
-TerminalInputParser::Type TerminalInputParser::ParseUTF8() {
+TerminalInputParser::Output TerminalInputParser::ParseUTF8() {
   unsigned char head = static_cast<unsigned char>(Current());
   for (int i = 0; i < 3; ++i, head <<= 1) {
     if ((head & 0b11000000) != 0b11000000)
@@ -86,7 +101,7 @@ TerminalInputParser::Type TerminalInputParser::ParseUTF8() {
   return CHARACTER;
 }
 
-TerminalInputParser::Type TerminalInputParser::ParseESC() {
+TerminalInputParser::Output TerminalInputParser::ParseESC() {
   if (!Eat())
     return UNCOMPLETED;
   switch (Current()) {
@@ -103,7 +118,7 @@ TerminalInputParser::Type TerminalInputParser::ParseESC() {
   }
 }
 
-TerminalInputParser::Type TerminalInputParser::ParseDCS() {
+TerminalInputParser::Output TerminalInputParser::ParseDCS() {
   // Parse until the string terminator ST.
   while (1) {
     if (!Eat())
@@ -122,19 +137,45 @@ TerminalInputParser::Type TerminalInputParser::ParseDCS() {
   }
 }
 
-TerminalInputParser::Type TerminalInputParser::ParseCSI() {
+TerminalInputParser::Output TerminalInputParser::ParseCSI() {
+  bool altered = false;
+  int argument = 0;
+  std::vector<int> arguments;
   while (true) {
     if (!Eat())
       return UNCOMPLETED;
 
-    if (Current() >= '0' && Current() <= '9')
+    if (Current() == '<') {
+      altered = true;
       continue;
+    }
 
-    if (Current() == ';')
+    if (Current() >= '0' && Current() <= '9') {
+      argument *= 10;
+      argument += int(Current() - '0');
       continue;
+    }
 
-    if (Current() >= ' ' && Current() <= '~')
-      return SPECIAL;
+    if (Current() == ';') {
+      arguments.push_back(argument);
+      argument = 0;
+      continue;
+    }
+
+    if (Current() >= ' ' && Current() <= '~' && Current() != '<') {
+      arguments.push_back(argument);
+      argument = 0;
+      switch (Current()) {
+        case 'M':
+          return ParseMouse(altered, true, std::move(arguments));
+        case 'm':
+          return ParseMouse(altered, false, std::move(arguments));
+        case 'R':
+          return ParseCursorReporting(std::move(arguments));
+        default:
+          return SPECIAL;
+      }
+    }
 
     // Invalid ESC in CSI.
     if (Current() == '\x1B')
@@ -142,7 +183,7 @@ TerminalInputParser::Type TerminalInputParser::ParseCSI() {
   }
 }
 
-TerminalInputParser::Type TerminalInputParser::ParseOSC() {
+TerminalInputParser::Output TerminalInputParser::ParseOSC() {
   // Parse until the string terminator ST.
   while (true) {
     if (!Eat())
@@ -156,4 +197,39 @@ TerminalInputParser::Type TerminalInputParser::ParseOSC() {
     return SPECIAL;
   }
 }
+
+TerminalInputParser::Output TerminalInputParser::ParseMouse(
+    bool altered,
+    bool pressed,
+    std::vector<int> arguments) {
+  if (arguments.size() != 3)
+    return SPECIAL;
+
+  (void)altered;
+
+  Output output(MOUSE);
+  output.mouse.button = Mouse::Button((arguments[0] & 3) +  //
+                                      ((arguments[0] & 64) >> 4));
+  output.mouse.motion = Mouse::Motion(pressed);
+  output.mouse.shift = bool(arguments[0] & 4);
+  output.mouse.meta = bool(arguments[0] & 8);
+  output.mouse.x = arguments[1];
+  output.mouse.y = arguments[2];
+  return output;
+}
+
+TerminalInputParser::Output TerminalInputParser::ParseCursorReporting(
+    std::vector<int> arguments) {
+  if (arguments.size() != 2)
+    return SPECIAL;
+  Output output(CURSOR_REPORTING);
+  output.cursor.y = arguments[0];
+  output.cursor.x = arguments[1];
+  return output;
+}
+
 }  // namespace ftxui
+
+// Copyright 2020 Arthur Sonzogni. All rights reserved.
+// Use of this source code is governed by the MIT license that can be found in
+// the LICENSE file.
diff --git a/src/ftxui/component/terminal_input_parser.hpp b/src/ftxui/component/terminal_input_parser.hpp
index ac0df243d00d5a63db61197ea65186fd547dcc8e..69645a6a386717d9d9cdd278d416ebcb300fe9f1 100644
--- a/src/ftxui/component/terminal_input_parser.hpp
+++ b/src/ftxui/component/terminal_input_parser.hpp
@@ -1,10 +1,13 @@
 #ifndef FTXUI_COMPONENT_TERMINAL_INPUT_PARSER
 #define FTXUI_COMPONENT_TERMINAL_INPUT_PARSER
 
-#include "ftxui/component/event.hpp"
-#include "ftxui/component/receiver.hpp"
+#include <memory>  // for unique_ptr
+#include <string>  // for string
+#include <vector>  // for vector
 
-#include <string>
+#include "ftxui/component/event.hpp"     // IWYU pragma: keep
+#include "ftxui/component/mouse.hpp"     // for Mouse
+#include "ftxui/component/receiver.hpp"  // for SenderImpl
 
 namespace ftxui {
 
@@ -20,18 +23,38 @@ class TerminalInputParser {
   bool Eat();
 
   enum Type {
-    UNCOMPLETED = 0,
-    DROP = 1,
-    CHARACTER = 2,
-    SPECIAL = 3,
+    UNCOMPLETED,
+    DROP,
+    CHARACTER,
+    SPECIAL,
+    MOUSE,
+    CURSOR_REPORTING,
   };
-  void Send(Type type);
-  Type Parse();
-  Type ParseUTF8();
-  Type ParseESC();
-  Type ParseDCS();
-  Type ParseCSI();
-  Type ParseOSC();
+
+  struct CursorReporting {
+    int x;
+    int y;
+  };
+
+  struct Output {
+    Type type;
+    union {
+      Mouse mouse;
+      CursorReporting cursor;
+    };
+
+    Output(Type type) : type(type) {}
+  };
+
+  void Send(Output type);
+  Output Parse();
+  Output ParseUTF8();
+  Output ParseESC();
+  Output ParseDCS();
+  Output ParseCSI();
+  Output ParseOSC();
+  Output ParseMouse(bool altered, bool pressed, std::vector<int> arguments);
+  Output ParseCursorReporting(std::vector<int> arguments);
 
   Sender<Event> out_;
   int position_ = -1;
diff --git a/src/ftxui/component/terminal_input_parser_test.cpp b/src/ftxui/component/terminal_input_parser_test.cpp
index 09bcfa40881794e34ff1421ad6a74561bb3787a5..b37b21634160b2e0e207657679219486419edb77 100644
--- a/src/ftxui/component/terminal_input_parser_test.cpp
+++ b/src/ftxui/component/terminal_input_parser_test.cpp
@@ -1,7 +1,9 @@
-#include "ftxui/component/terminal_input_parser.hpp"
-#include "ftxui/component/receiver.hpp"
+#include <gtest/gtest-message.h>    // for Message
+#include <gtest/gtest-test-part.h>  // for TestPartResult
 
-#include "gtest/gtest.h"
+#include "ftxui/component/receiver.hpp"  // for MakeReceiver, ReceiverImpl
+#include "ftxui/component/terminal_input_parser.hpp"
+#include "gtest/gtest_pred_impl.h"  // for AssertionResult, Test, Suite...
 
 using namespace ftxui;
 
@@ -66,6 +68,84 @@ TEST(Event, EscapeKeyEnoughWait) {
   EXPECT_FALSE(event_receiver->Receive(&received));
 }
 
+TEST(Event, MouseLeftClick) {
+  auto event_receiver = MakeReceiver<Event>();
+  {
+    auto parser = TerminalInputParser(event_receiver->MakeSender());
+    parser.Add('\x1B');
+    parser.Add('[');
+    parser.Add('3');
+    parser.Add('2');
+    parser.Add(';');
+    parser.Add('1');
+    parser.Add('2');
+    parser.Add(';');
+    parser.Add('4');
+    parser.Add('2');
+    parser.Add('M');
+  }
+
+  Event received;
+  EXPECT_TRUE(event_receiver->Receive(&received));
+  EXPECT_TRUE(received.is_mouse());
+  EXPECT_EQ(Mouse::Left, received.mouse().button);
+  EXPECT_EQ(12, received.mouse().x);
+  EXPECT_EQ(42, received.mouse().y);
+  EXPECT_FALSE(event_receiver->Receive(&received));
+}
+
+TEST(Event, MouseMiddleClick) {
+  auto event_receiver = MakeReceiver<Event>();
+  {
+    auto parser = TerminalInputParser(event_receiver->MakeSender());
+    parser.Add('\x1B');
+    parser.Add('[');
+    parser.Add('3');
+    parser.Add('3');
+    parser.Add(';');
+    parser.Add('1');
+    parser.Add('2');
+    parser.Add(';');
+    parser.Add('4');
+    parser.Add('2');
+    parser.Add('M');
+  }
+
+  Event received;
+  EXPECT_TRUE(event_receiver->Receive(&received));
+  EXPECT_TRUE(received.is_mouse());
+  EXPECT_EQ(Mouse::Middle, received.mouse().button);
+  EXPECT_EQ(12, received.mouse().x);
+  EXPECT_EQ(42, received.mouse().y);
+  EXPECT_FALSE(event_receiver->Receive(&received));
+}
+
+TEST(Event, MouseRightClick) {
+  auto event_receiver = MakeReceiver<Event>();
+  {
+    auto parser = TerminalInputParser(event_receiver->MakeSender());
+    parser.Add('\x1B');
+    parser.Add('[');
+    parser.Add('3');
+    parser.Add('4');
+    parser.Add(';');
+    parser.Add('1');
+    parser.Add('2');
+    parser.Add(';');
+    parser.Add('4');
+    parser.Add('2');
+    parser.Add('M');
+  }
+
+  Event received;
+  EXPECT_TRUE(event_receiver->Receive(&received));
+  EXPECT_TRUE(received.is_mouse());
+  EXPECT_EQ(Mouse::Right, received.mouse().button);
+  EXPECT_EQ(12, received.mouse().x);
+  EXPECT_EQ(42, received.mouse().y);
+  EXPECT_FALSE(event_receiver->Receive(&received));
+}
+
 // Copyright 2020 Arthur Sonzogni. All rights reserved.
 // Use of this source code is governed by the MIT license that can be found in
 // the LICENSE file.
diff --git a/src/ftxui/component/toggle.cpp b/src/ftxui/component/toggle.cpp
index c7be19e28ffc9be77da25542b8da323bb7476576..ca064617694b686fa096c7f9f84e3edbf20fea48 100644
--- a/src/ftxui/component/toggle.cpp
+++ b/src/ftxui/component/toggle.cpp
@@ -1,29 +1,43 @@
-#include "ftxui/component/toggle.hpp"
+#include <stddef.h>   // for size_t
+#include <algorithm>  // for max, min
+#include <memory>     // for shared_ptr, alloca...
+#include <utility>    // for move
 
-#include <algorithm>
+#include "ftxui/component/captured_mouse.hpp"      // for CapturedMouse
+#include "ftxui/component/mouse.hpp"               // for Mouse, Mouse::Left
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+#include "ftxui/component/toggle.hpp"
 
 namespace ftxui {
 
 Element Toggle::Render() {
-  bool is_focused = Focused();
-
   Elements children;
+  bool is_toggle_focused = Focused();
+  boxes_.resize(entries.size());
   for (size_t i = 0; i < entries.size(); ++i) {
     // Separator.
     if (i != 0)
       children.push_back(separator());
 
-    // Entry.
-    auto style = (selected != int(i))
-                     ? normal_style
-                     : is_focused ? focused_style : selected_style;
-    auto focused = (selected != int(i)) ? nothing : is_focused ? focus : select;
-    children.push_back(text(entries[i]) | style | focused);
+    bool is_focused = (focused == int(i)) && is_toggle_focused;
+    bool is_selected = (selected == int(i));
+
+    auto style = is_selected
+                     ? (is_focused ? selected_focused_style : selected_style)
+                     : (is_focused ? focused_style : normal_style);
+    auto focus_management = !is_selected        ? nothing
+                            : is_toggle_focused ? focus
+                                                : select;
+    children.push_back(text(entries[i]) | style | focus_management |
+                       reflect(boxes_[i]));
   }
   return hbox(std::move(children));
 }
 
 bool Toggle::OnEvent(Event event) {
+  if (event.is_mouse())
+    return OnMouseEvent(event);
+
   int old_selected = selected;
   if (event == Event::ArrowLeft || event == Event::Character('h'))
     selected--;
@@ -37,6 +51,7 @@ bool Toggle::OnEvent(Event event) {
   selected = std::max(0, std::min(int(entries.size()) - 1, selected));
 
   if (old_selected != selected) {
+    focused = selected;
     on_change();
     return true;
   }
@@ -49,6 +64,28 @@ bool Toggle::OnEvent(Event event) {
   return false;
 }
 
+bool Toggle::OnMouseEvent(Event event) {
+  if (!CaptureMouse(event))
+    return false;
+  for (int i = 0; i < boxes_.size(); ++i) {
+    if (!boxes_[i].Contain(event.mouse().x, event.mouse().y))
+      continue;
+
+    TakeFocus();
+    focused = i;
+    if (event.mouse().button == Mouse::Left &&
+        event.mouse().motion == Mouse::Pressed) {
+      TakeFocus();
+      if (selected != i) {
+        selected = i;
+        on_change();
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
 }  // namespace ftxui
 
 // Copyright 2020 Arthur Sonzogni. All rights reserved.
diff --git a/src/ftxui/component/toggle_test.cpp b/src/ftxui/component/toggle_test.cpp
index acb19ef3e430f9bfef28aeb8b8e34865ea6d25c0..4842d2c06d2bfe7ef02d20431190d1c434bb31e0 100644
--- a/src/ftxui/component/toggle_test.cpp
+++ b/src/ftxui/component/toggle_test.cpp
@@ -1,6 +1,10 @@
-#include "ftxui/component/toggle.hpp"
+#include <gtest/gtest-message.h>  // for Message
+#include <gtest/gtest-test-part.h>  // for TestPartResult, SuiteApiResolver, TestFactoryImpl
 
-#include "gtest/gtest.h"
+#include "ftxui/component/event.hpp"  // for Event, Event::ArrowLeft, Event::ArrowRight, Event::Return, Event::Tab, Event::TabReverse
+#include "ftxui/component/mouse.hpp"  // for ftxui
+#include "ftxui/component/toggle.hpp"
+#include "gtest/gtest_pred_impl.h"  // for AssertionResult, EXPECT_EQ, Test, EXPECT_TRUE, EXPECT_FALSE, TEST
 
 using namespace ftxui;
 
diff --git a/src/ftxui/dom/blink.cpp b/src/ftxui/dom/blink.cpp
index 8356d836bb2dcbe733a66574af92c7642e2ea7f9..57a3a2304c40021dd00de41afc236687aad6b42b 100644
--- a/src/ftxui/dom/blink.cpp
+++ b/src/ftxui/dom/blink.cpp
@@ -1,5 +1,10 @@
+#include <memory>
+
 #include "ftxui/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
 #include "ftxui/dom/node_decorator.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/bold.cpp b/src/ftxui/dom/bold.cpp
index f959e814bdf7fa569a0d5ab52f2f90615c038f07..1d5c3c7bdc855a835dea7a4b3dd42a013646351c 100644
--- a/src/ftxui/dom/bold.cpp
+++ b/src/ftxui/dom/bold.cpp
@@ -1,5 +1,10 @@
+#include <memory>
+
 #include "ftxui/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
 #include "ftxui/dom/node_decorator.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/border.cpp b/src/ftxui/dom/border.cpp
index 2d1463772e742360e70efc8e92a21e54ceb857b1..a7ce81c5720d2356b9f1acaae41c8110abe64c2f 100644
--- a/src/ftxui/dom/border.cpp
+++ b/src/ftxui/dom/border.cpp
@@ -1,7 +1,14 @@
-#include <algorithm>
-
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
+#include <algorithm>  // for max
+#include <iterator>   // for begin, end
+#include <memory>     // for make_shared, __shared_ptr_access
+#include <utility>    // for move
+#include <vector>     // for vector
+
+#include "ftxui/dom/elements.hpp"  // for unpack, Element, Decorator, Elements, border, borderWith, window
+#include "ftxui/dom/node.hpp"         // for Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
+#include "ftxui/screen/screen.hpp"    // for Pixel, Screen
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/clear_under.cpp b/src/ftxui/dom/clear_under.cpp
index da0c60096a783edd12e4919c550b6b7649e9a232..23fb36cbe923be98535735cb48fe15e7d235b3ea 100644
--- a/src/ftxui/dom/clear_under.cpp
+++ b/src/ftxui/dom/clear_under.cpp
@@ -1,5 +1,10 @@
+#include <memory>
+
 #include "ftxui/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
 #include "ftxui/dom/node_decorator.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/color.cpp b/src/ftxui/dom/color.cpp
index 023dc8f7a8488b2b78cb2f09fd22948ccb56ff6a..475d97865543deaecda23ab4f9a2841ad25f5e93 100644
--- a/src/ftxui/dom/color.cpp
+++ b/src/ftxui/dom/color.cpp
@@ -1,5 +1,10 @@
+#include <memory>
+
 #include "ftxui/dom/elements.hpp"
 #include "ftxui/dom/node_decorator.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/color.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/composite_decorator.cpp b/src/ftxui/dom/composite_decorator.cpp
index c8183276218ed136eda50d9b2566d5cf6d1eeff6..007057ccfdeb7d90c83e90d7b0dc023502e8e8cb 100644
--- a/src/ftxui/dom/composite_decorator.cpp
+++ b/src/ftxui/dom/composite_decorator.cpp
@@ -1,5 +1,5 @@
+
 #include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/dbox.cpp b/src/ftxui/dom/dbox.cpp
index ea737910302d904c9fa3d468373256b5ce2fe3be..e39283bd7fb1829885678f09a14d6eff83d03624 100644
--- a/src/ftxui/dom/dbox.cpp
+++ b/src/ftxui/dom/dbox.cpp
@@ -1,7 +1,12 @@
-#include <algorithm>
-
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
+#include <algorithm>  // for max
+#include <memory>     // for __shared_ptr_access, shared_ptr, make_shared
+#include <utility>    // for move
+#include <vector>     // for vector
+
+#include "ftxui/dom/elements.hpp"     // for Element, Elements, dbox
+#include "ftxui/dom/node.hpp"         // for Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/dim.cpp b/src/ftxui/dom/dim.cpp
index 7b6b68ad6cece50dede44507387b35a06adb4553..296ea1d79b55d8b90dda1acb2f6e0f633cf00dbb 100644
--- a/src/ftxui/dom/dim.cpp
+++ b/src/ftxui/dom/dim.cpp
@@ -1,5 +1,10 @@
+#include <memory>
+
 #include "ftxui/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
 #include "ftxui/dom/node_decorator.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/flex.cpp b/src/ftxui/dom/flex.cpp
index bf2942e6cb4cd8cb735092df60ed2079e68998de..303481c48adc79a7212ed964675ab271fb7e85f0 100644
--- a/src/ftxui/dom/flex.cpp
+++ b/src/ftxui/dom/flex.cpp
@@ -1,5 +1,10 @@
+#include <memory>
+#include <vector>
+
 #include "ftxui/dom/elements.hpp"
 #include "ftxui/dom/node.hpp"
+#include "ftxui/dom/requirement.hpp"
+#include "ftxui/screen/box.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/frame.cpp b/src/ftxui/dom/frame.cpp
index 7e25c8c09e8cce8721f23f36d8c300cb04f80c29..05f3ea92726ead77998318491f38eea21a5f9a4f 100644
--- a/src/ftxui/dom/frame.cpp
+++ b/src/ftxui/dom/frame.cpp
@@ -1,8 +1,14 @@
-#include <algorithm>
-
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
-#include "ftxui/util/autoreset.hpp"
+#include <algorithm>  // for max, min
+#include <memory>     // for make_shared, shared_ptr, __shared_ptr_access
+#include <utility>    // for move
+#include <vector>     // for vector
+
+#include "ftxui/dom/elements.hpp"  // for Element, unpack, focus, frame, select, xframe, yframe
+#include "ftxui/dom/node.hpp"  // for Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement, Requirement::FOCUSED, Requirement::SELECTED
+#include "ftxui/screen/box.hpp"      // for Box
+#include "ftxui/screen/screen.hpp"   // for Screen, Screen::Cursor
+#include "ftxui/util/autoreset.hpp"  // for AutoReset
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/gauge.cpp b/src/ftxui/dom/gauge.cpp
index d448036a3c49afe72939d79589240a92efd48295..fe45c4b6a0bdeade8e7d5280d493c31cff00d178 100644
--- a/src/ftxui/dom/gauge.cpp
+++ b/src/ftxui/dom/gauge.cpp
@@ -1,5 +1,9 @@
+#include <memory>
+
 #include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/requirement.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/gauge_test.cpp b/src/ftxui/dom/gauge_test.cpp
index 10563967268329f5d057d034dcb1e3036995309a..0eb3275e5acd85808748bad2f5b09b48ad1d19c8 100644
--- a/src/ftxui/dom/gauge_test.cpp
+++ b/src/ftxui/dom/gauge_test.cpp
@@ -1,6 +1,12 @@
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/screen/screen.hpp"
-#include "gtest/gtest.h"
+#include <gtest/gtest-message.h>    // for Message
+#include <gtest/gtest-test-part.h>  // for TestPartResult
+#include <memory>                   // for allocator
+
+#include "ftxui/dom/elements.hpp"   // for gauge
+#include "ftxui/dom/node.hpp"       // for Render
+#include "ftxui/screen/box.hpp"     // for ftxui
+#include "ftxui/screen/screen.hpp"  // for Screen
+#include "gtest/gtest_pred_impl.h"  // for Test, SuiteApiResolver, EXPECT_EQ
 
 using namespace ftxui;
 using namespace ftxui;
diff --git a/src/ftxui/dom/graph.cpp b/src/ftxui/dom/graph.cpp
index 67f0cd36a826c50b4564b816b08ebdeb78342b05..4261bdefc30989988cf5e42d8efbda507ff93d4d 100644
--- a/src/ftxui/dom/graph.cpp
+++ b/src/ftxui/dom/graph.cpp
@@ -1,4 +1,12 @@
-#include "ftxui/dom/elements.hpp"
+#include <functional>  // for function
+#include <memory>      // for make_shared
+#include <vector>      // for vector
+
+#include "ftxui/dom/elements.hpp"     // for GraphFunction, Element, graph
+#include "ftxui/dom/node.hpp"         // for Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
+#include "ftxui/screen/screen.hpp"    // for Screen
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/hbox.cpp b/src/ftxui/dom/hbox.cpp
index 3ff91e008e327a2b0c05dd2305d396e86595e686..43757e6fae5a1acae0a33bef03f53772e37f44d5 100644
--- a/src/ftxui/dom/hbox.cpp
+++ b/src/ftxui/dom/hbox.cpp
@@ -1,7 +1,12 @@
-#include <algorithm>
-
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
+#include <algorithm>  // for max
+#include <memory>     // for __shared_ptr_access, shared_ptr, make_shared
+#include <utility>    // for move
+#include <vector>     // for vector
+
+#include "ftxui/dom/elements.hpp"     // for Element, Elements, hbox
+#include "ftxui/dom/node.hpp"         // for Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/hbox_test.cpp b/src/ftxui/dom/hbox_test.cpp
index dbeac3a65b07187172c36226bc4dd6318d9a4f4a..fc5ca6c06d8c40a880d26bf932d6beb65bce44c0 100644
--- a/src/ftxui/dom/hbox_test.cpp
+++ b/src/ftxui/dom/hbox_test.cpp
@@ -1,6 +1,13 @@
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/screen/screen.hpp"
-#include "gtest/gtest.h"
+#include <gtest/gtest-message.h>    // for Message
+#include <gtest/gtest-test-part.h>  // for TestPartResult
+#include <string>                   // for allocator, basic_string, string
+#include <vector>                   // for vector
+
+#include "ftxui/dom/elements.hpp"   // for text, operator|, Element, flex_grow
+#include "ftxui/dom/node.hpp"       // for Render
+#include "ftxui/screen/box.hpp"     // for ftxui
+#include "ftxui/screen/screen.hpp"  // for Screen
+#include "gtest/gtest_pred_impl.h"  // for Test, SuiteApiResolver, EXPECT_EQ
 
 using namespace ftxui;
 using namespace ftxui;
diff --git a/src/ftxui/dom/hflow.cpp b/src/ftxui/dom/hflow.cpp
index ee6ff0470fd53ce9a873f5a0b4fef90cb3c3119a..eb20233c5769e56b0d1d307fceb6cba62f1f055a 100644
--- a/src/ftxui/dom/hflow.cpp
+++ b/src/ftxui/dom/hflow.cpp
@@ -1,7 +1,12 @@
-#include <algorithm>
+#include <algorithm>  // for max
+#include <memory>     // for __shared_ptr_access, make_shared, shared_ptr
+#include <utility>    // for move
+#include <vector>     // for vector
 
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"     // for Element, Elements, hflow
+#include "ftxui/dom/node.hpp"         // for Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/inverted.cpp b/src/ftxui/dom/inverted.cpp
index 10549909eb869cb3aa1f78007d42fa512679388b..c85954637bd194040f77301fb9e51543881d7180 100644
--- a/src/ftxui/dom/inverted.cpp
+++ b/src/ftxui/dom/inverted.cpp
@@ -1,5 +1,10 @@
+#include <memory>
+#include <utility>
+
 #include "ftxui/dom/elements.hpp"
 #include "ftxui/dom/node_decorator.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/node.cpp b/src/ftxui/dom/node.cpp
index d5f08c7d1dd3ac39c01563cd505332adeb96daba..9ed078b65687a0fcd1ec1ce78fd0510a82121c37 100644
--- a/src/ftxui/dom/node.cpp
+++ b/src/ftxui/dom/node.cpp
@@ -1,4 +1,7 @@
+#include <utility>
+
 #include "ftxui/dom/node.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/node_decorator.cpp b/src/ftxui/dom/node_decorator.cpp
index db5c39a58a852723a009a3d3ee45d3a0a7c5c2ac..b98c2c2a93c0b0d1ff026a00227b0be55a9c0be3 100644
--- a/src/ftxui/dom/node_decorator.cpp
+++ b/src/ftxui/dom/node_decorator.cpp
@@ -1,4 +1,9 @@
+#include <memory>  // for __shared_ptr_access
+#include <vector>  // for vector
+
 #include "ftxui/dom/node_decorator.hpp"
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/node_decorator.hpp b/src/ftxui/dom/node_decorator.hpp
index 0336b04c823e3677fd80b2ca9510d87e3006efa1..a9f1d4f43f25c1bf9a29e58b8476531a7eeea904 100644
--- a/src/ftxui/dom/node_decorator.hpp
+++ b/src/ftxui/dom/node_decorator.hpp
@@ -1,9 +1,12 @@
 #ifndef FTXUI_DOM_NODE_DECORATOR_H_
 #define FTXUI_DOM_NODE_DECORATOR_H_
 
-#include "ftxui/dom/node.hpp"
+#include <utility>  // for move
+
+#include "ftxui/dom/node.hpp"  // for Node, Elements
 
 namespace ftxui {
+struct Box;
 
 // Helper class.
 class NodeDecorator : public Node {
diff --git a/src/ftxui/dom/paragraph.cpp b/src/ftxui/dom/paragraph.cpp
index 7a8a8e7b2ca907e3bb89a47febf98fad2ad3e229..a90c18d7581e57146658c5360e244762f572e666 100644
--- a/src/ftxui/dom/paragraph.cpp
+++ b/src/ftxui/dom/paragraph.cpp
@@ -1,4 +1,5 @@
 #include <sstream>
+#include <string>
 
 #include "ftxui/dom/elements.hpp"
 
diff --git a/src/ftxui/dom/reflect.cpp b/src/ftxui/dom/reflect.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..79998ad610d1bbac1832c70ccf73b6adf673db2d
--- /dev/null
+++ b/src/ftxui/dom/reflect.cpp
@@ -0,0 +1,44 @@
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/requirement.hpp"
+#include "ftxui/screen/box.hpp"
+
+namespace ftxui {
+
+// Helper class.
+class Reflect : public Node {
+ public:
+  Reflect(Element child, Box& box)
+      : Node(unpack(std::move(child))), box_(box) {}
+  ~Reflect() override {}
+
+  void ComputeRequirement() final {
+    Node::ComputeRequirement();
+    requirement_ = children[0]->requirement();
+  }
+
+  void SetBox(Box box) final {
+    box_ = box;
+    Node::SetBox(box_);
+    children[0]->SetBox(box_);
+  }
+
+ private:
+  Box& box_;
+};
+
+Decorator reflect(Box& box) {
+  return [&](Element child) -> Element {
+    return std::make_shared<Reflect>(std::move(child), box);
+  };
+}
+
+}  // namespace ftxui
+
+// Copyright 2020 Arthur Sonzogni. All rights reserved.
+// Use of this source code is governed by the MIT license that can be found in
+// the LICENSE file.
diff --git a/src/ftxui/dom/separator.cpp b/src/ftxui/dom/separator.cpp
index 0997d6e4a3d4884d34e0cfff9fabbfa74a6ac46d..243249dc334eb461fcd7328573980ca1cec31adf 100644
--- a/src/ftxui/dom/separator.cpp
+++ b/src/ftxui/dom/separator.cpp
@@ -1,5 +1,9 @@
+#include <memory>
+
 #include "ftxui/dom/elements.hpp"
 #include "ftxui/dom/node.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/size.cpp b/src/ftxui/dom/size.cpp
index 5bb4cb417fd24c3f3501fa192e475947db1e7856..f5621b68a8a5dc6ddc519b036eda9ecb039bf6dd 100644
--- a/src/ftxui/dom/size.cpp
+++ b/src/ftxui/dom/size.cpp
@@ -1,7 +1,13 @@
-#include <algorithm>
+#include <stddef.h>   // for size_t
+#include <algorithm>  // for min, max
+#include <memory>     // for make_shared, __shared_ptr_access
+#include <utility>    // for move
+#include <vector>     // for vector
 
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
+#include "ftxui/dom/elements.hpp"  // for Constraint, Direction, EQUAL, GREATER_THAN, LESS_THAN, WIDTH, unpack, Decorator, Element, size
+#include "ftxui/dom/node.hpp"      // for Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/spinner.cpp b/src/ftxui/dom/spinner.cpp
index 24ea38ba74f0adbd0d47124862d0e7a19a0c3508..e415acceb14bf5c84e473538c9cf4351d907be4c 100644
--- a/src/ftxui/dom/spinner.cpp
+++ b/src/ftxui/dom/spinner.cpp
@@ -1,5 +1,9 @@
+#include <stddef.h>
+#include <memory>
+#include <string>
+#include <vector>
+
 #include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/text.cpp b/src/ftxui/dom/text.cpp
index 0a30f7dd55a02759f39877876e9a0230c534ffed..a8ade9aee99430158fc4b0bc992d0fd367a5539b 100644
--- a/src/ftxui/dom/text.cpp
+++ b/src/ftxui/dom/text.cpp
@@ -1,7 +1,13 @@
-#include <algorithm>
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
-#include "ftxui/screen/string.hpp"
+#include <algorithm>  // for max
+#include <memory>     // for make_shared
+#include <string>     // for wstring
+
+#include "ftxui/dom/elements.hpp"     // for Element, text, vtext
+#include "ftxui/dom/node.hpp"         // for Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
+#include "ftxui/screen/screen.hpp"    // for Screen
+#include "ftxui/screen/string.hpp"    // for wchar_width, wstring_width
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/text_test.cpp b/src/ftxui/dom/text_test.cpp
index 34fe2a55ce1a6f5b23e5551acfca80dcd2c4a60a..a1a55518cd290261b72fd34b9012ec3c500e66c3 100644
--- a/src/ftxui/dom/text_test.cpp
+++ b/src/ftxui/dom/text_test.cpp
@@ -1,8 +1,12 @@
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/screen/screen.hpp"
-#include "gtest/gtest.h"
+#include <gtest/gtest-message.h>    // for Message
+#include <gtest/gtest-test-part.h>  // for TestPartResult
+#include <memory>                   // for allocator
+
+#include "ftxui/dom/elements.hpp"   // for text, Element, operator|, border
+#include "ftxui/screen/box.hpp"     // for ftxui
+#include "ftxui/screen/screen.hpp"  // for Screen
+#include "gtest/gtest_pred_impl.h"  // for Test, SuiteApiResolver, EXPECT_EQ
 
-using namespace ftxui;
 using namespace ftxui;
 
 TEST(TextTest, ScreenHeightSmaller) {
diff --git a/src/ftxui/dom/underlined.cpp b/src/ftxui/dom/underlined.cpp
index b04a1108e06323ad92584826a0a8740f53ef50e9..7a3a50f127465a5c864e18410150e8981efdae46 100644
--- a/src/ftxui/dom/underlined.cpp
+++ b/src/ftxui/dom/underlined.cpp
@@ -1,5 +1,10 @@
+#include <memory>
+#include <utility>
+
 #include "ftxui/dom/elements.hpp"
 #include "ftxui/dom/node_decorator.hpp"
+#include "ftxui/screen/box.hpp"
+#include "ftxui/screen/screen.hpp"
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/util.cpp b/src/ftxui/dom/util.cpp
index bc86b1b2ba64bb72a83f9df2dcb8fc2d841ebca7..1770611915ee03dbfc3c6ec55491cddbcbf0eb04 100644
--- a/src/ftxui/dom/util.cpp
+++ b/src/ftxui/dom/util.cpp
@@ -1,4 +1,7 @@
-#include "ftxui/dom/elements.hpp"
+#include <functional>  // for function
+#include <utility>     // for move
+
+#include "ftxui/dom/elements.hpp"  // for Decorator, Element, Elements, operator|, nothing
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/vbox.cpp b/src/ftxui/dom/vbox.cpp
index e514ae0c9943712d00e08b8bd2bdd9395ca4e446..0686498225bd9cb7dac62360274fedf814ecd2b7 100644
--- a/src/ftxui/dom/vbox.cpp
+++ b/src/ftxui/dom/vbox.cpp
@@ -1,8 +1,12 @@
-#include <algorithm>
-#include <iostream>
-
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/dom/node.hpp"
+#include <algorithm>  // for max
+#include <memory>     // for __shared_ptr_access, shared_ptr, make_shared
+#include <utility>    // for move
+#include <vector>     // for vector
+
+#include "ftxui/dom/elements.hpp"     // for Element, Elements, vbox
+#include "ftxui/dom/node.hpp"         // for Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/box.hpp"       // for Box
 
 namespace ftxui {
 
diff --git a/src/ftxui/dom/vbox_test.cpp b/src/ftxui/dom/vbox_test.cpp
index 917afd9d7479ba5a30159ca65349c32ab5488989..19aa8b9c9f110b8f8b86c678097b778e84242d65 100644
--- a/src/ftxui/dom/vbox_test.cpp
+++ b/src/ftxui/dom/vbox_test.cpp
@@ -1,6 +1,14 @@
-#include "ftxui/dom/elements.hpp"
-#include "ftxui/screen/screen.hpp"
-#include "gtest/gtest.h"
+#include <gtest/gtest-message.h>    // for Message
+#include <gtest/gtest-test-part.h>  // for TestPartResult
+#include <algorithm>                // for remove
+#include <string>                   // for allocator, basic_string, string
+#include <vector>                   // for vector
+
+#include "ftxui/dom/elements.hpp"   // for vtext, operator|, Element, flex_grow
+#include "ftxui/dom/node.hpp"       // for Render
+#include "ftxui/screen/box.hpp"     // for ftxui
+#include "ftxui/screen/screen.hpp"  // for Screen
+#include "gtest/gtest_pred_impl.h"  // for Test, SuiteApiResolver, EXPECT_EQ
 
 using namespace ftxui;
 using namespace ftxui;
diff --git a/src/ftxui/screen/box.cpp b/src/ftxui/screen/box.cpp
index b8ed1ee89bdf8d1c9e0f2ff0bf65b1caf67dc235..07826f819a83a44162e338906a60bb7120b97c5b 100644
--- a/src/ftxui/screen/box.cpp
+++ b/src/ftxui/screen/box.cpp
@@ -14,6 +14,16 @@ Box Box::Intersection(Box a, Box b) {
       std::min(a.y_max, b.y_max),
   };
 }
+
+/// @return whether (x,y) is contained inside the box.
+/// @ingroup screen
+bool Box::Contain(int x, int y) {
+  return x_min <= x &&  //
+         x_max >= x &&  //
+         y_min <= y &&  //
+         y_max >= y;
+}
+
 }  // namespace ftxui
 
 // Copyright 2020 Arthur Sonzogni. All rights reserved.
diff --git a/src/ftxui/screen/color.cpp b/src/ftxui/screen/color.cpp
index e71547ee8eb004ec52509e74d0442ac07fd61889..ca2a4597f7b3767df9711ad5720c269a4d449f2a 100644
--- a/src/ftxui/screen/color.cpp
+++ b/src/ftxui/screen/color.cpp
@@ -1,7 +1,4 @@
 #include "ftxui/screen/color.hpp"
-
-#include <algorithm>
-
 #include "ftxui/screen/color_info.hpp"
 #include "ftxui/screen/string.hpp"
 #include "ftxui/screen/terminal.hpp"
diff --git a/src/ftxui/screen/color_info.cpp b/src/ftxui/screen/color_info.cpp
index 2a12a2f655b88130abaf558498cbfbdc2dd6030c..a63001117577368e2079ea9f021fc7afb042390a 100644
--- a/src/ftxui/screen/color_info.cpp
+++ b/src/ftxui/screen/color_info.cpp
@@ -1,4 +1,5 @@
 #include "ftxui/screen/color_info.hpp"
+#include "ftxui/screen/color.hpp"  // for Color, Color::Palette16, Color::Palette256
 
 namespace ftxui {
 
diff --git a/src/ftxui/screen/screen.cpp b/src/ftxui/screen/screen.cpp
index d83e42455daf1a96e114f274c7e31021b2a79d3f..5a3dbd195439873519dd5736ad5c507b1271f5b0 100644
--- a/src/ftxui/screen/screen.cpp
+++ b/src/ftxui/screen/screen.cpp
@@ -1,12 +1,12 @@
-#include "ftxui/screen/screen.hpp"
-
-#include <algorithm>
-#include <sstream>
-#include <iostream>
+#include <algorithm>  // for min
+#include <iostream>  // for operator<<, basic_ostream, wstringstream, stringstream, flush, cout, ostream
+#include <sstream>   // IWYU pragma: keep
 
-#include "ftxui/dom/node.hpp"
-#include "ftxui/screen/string.hpp"
-#include "ftxui/screen/terminal.hpp"
+#include "ftxui/dom/node.hpp"         // for Element, Node
+#include "ftxui/dom/requirement.hpp"  // for Requirement
+#include "ftxui/screen/screen.hpp"
+#include "ftxui/screen/string.hpp"    // for to_string, wchar_width
+#include "ftxui/screen/terminal.hpp"  // for Terminal::Dimensions, Terminal
 
 #if defined(_WIN32)
 #define WIN32_LEAN_AND_MEAN
@@ -169,9 +169,9 @@ std::string Screen::ToString() {
 
       auto width = wchar_width(c);
       if (width <= 0) {
-          // Avoid an infinite loop for non-printable characters
-          c = L' ';
-          width = 1;
+        // Avoid an infinite loop for non-printable characters
+        c = L' ';
+        width = 1;
       }
       ss << c;
       x += width;
@@ -184,7 +184,7 @@ std::string Screen::ToString() {
 }
 
 void Screen::Print() {
-  std::cout << ToString() << std::flush << (char)0;
+  std::cout << ToString() << '\0' << std::flush;
 }
 
 /// @brief Access a character a given position.
diff --git a/src/ftxui/screen/terminal.cpp b/src/ftxui/screen/terminal.cpp
index fea187e3d9ba52bc2c36ed27d45a41b427da67b0..213377f41d96c529435621b82dfbbfcbf5c4c0e1 100644
--- a/src/ftxui/screen/terminal.cpp
+++ b/src/ftxui/screen/terminal.cpp
@@ -1,8 +1,7 @@
-#include "ftxui/screen/terminal.hpp"
-
-#include <stdio.h>
+#include <cstdlib>  // for getenv
+#include <string>   // for string, allocator
 
-#include <cstdlib>
+#include "ftxui/screen/terminal.hpp"
 
 #if defined(_WIN32)
 #define WIN32_LEAN_AND_MEAN
@@ -13,12 +12,10 @@
 
 #include <Windows.h>
 #else
-#include <sys/ioctl.h>
-#include <unistd.h>
+#include <sys/ioctl.h>  // for winsize, ioctl, TIOCGWINSZ
+#include <unistd.h>     // for STDOUT_FILENO
 #endif
 
-#include <iostream>
-
 namespace ftxui {
 
 Terminal::Dimensions Terminal::Size() {
diff --git a/src/ftxui/screen/wcwidth.cpp b/src/ftxui/screen/wcwidth.cpp
index 6d3bcdbc7511ca9b6f30ea82e9806911f1aa2f01..7791a3e482bdda23d51e4fc2edb350825e369910 100644
--- a/src/ftxui/screen/wcwidth.cpp
+++ b/src/ftxui/screen/wcwidth.cpp
@@ -59,7 +59,7 @@
  * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
  */
 
-#include <wchar.h>
+#include <string>
 
 #include "ftxui/screen/string.hpp"
 
diff --git a/tools/iwyu.sh b/tools/iwyu.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1e1f62b10fe96924decf5bb6abb23b40b0c4422c
--- /dev/null
+++ b/tools/iwyu.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+cd "$(dirname "$0")"
+cd ..
+mapping_dir=$(pwd)
+mkdir -p iwyu
+cd iwyu
+rm * -rf
+echo $CMAKE_CXX_INCLUDE_WHAT_YOU_USE
+cmake .. -DFTXUI_BUILD_TESTS=ON -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE="iwyu;-Xiwyu;--cxx17ns;-Xiwyu;--mapping_file=${mapping_dir}/iwyu.imp;-Xiwyu;--verbose=3"
+make -j 2>out
+fix_include --comments < out