diff --git a/examples/component/CMakeLists.txt b/examples/component/CMakeLists.txt
index 38c0e98922a575c6078c9683badc00511b238a74..d1bab8c9fbdc7c16d22ec31fd33e016216d142bf 100644
--- a/examples/component/CMakeLists.txt
+++ b/examples/component/CMakeLists.txt
@@ -3,3 +3,4 @@ example(menu)
 example(menu2)
 example(menu_style)
 example(toggle)
+example(tab)
diff --git a/examples/component/input.cpp b/examples/component/input.cpp
index 72ea012d44cb39583cdaf3b591ac0189eedd5cda..1a521bd427962f266859221c88ae021ec72ca406 100644
--- a/examples/component/input.cpp
+++ b/examples/component/input.cpp
@@ -45,7 +45,7 @@ class MyComponent : ComponentVertical {
 };
 
 int main(int argc, const char* argv[]) {
-  ftxui::ScreenInteractive screen(60, 5);
+  auto screen = ftxui::ScreenInteractive::TerminalOutput();
   MyComponent component(screen.delegate());
   component.on_enter = screen.ExitLoopClosure();
   screen.Loop();
diff --git a/examples/component/menu.cpp b/examples/component/menu.cpp
index 2dd62340ef56ffa6fb94abacb91521613589e892..177bd74a0f704da79a0b531ce1f6890b0a089a6d 100644
--- a/examples/component/menu.cpp
+++ b/examples/component/menu.cpp
@@ -7,7 +7,7 @@
 
 int main(int argc, const char *argv[])
 {
-  ftxui::ScreenInteractive screen(30,3);
+  auto screen = ftxui::ScreenInteractive::FixedSize(30, 3);
   ftxui::component::Menu menu(screen.delegate());
   menu.entries = {
     L"entry 1",
diff --git a/examples/component/menu2.cpp b/examples/component/menu2.cpp
index ee45654b956577b9c9ffd96f9d50b7db1e66d9f8..50a7ba0436a5b2fef618f804380ffc6235627078 100644
--- a/examples/component/menu2.cpp
+++ b/examples/component/menu2.cpp
@@ -40,29 +40,25 @@ class MyComponent : ComponentHorizontal {
            // -------- Top panel --------------
            hbox(
              // -------- Left Menu --------------
-             flex(
-               vbox(
-                 hcenter(bold(text(L"Percentage by 10%"))),
-                 separator(),
-                 left_menu.Render()
-               )
-             ),
+             vbox(
+               hcenter(bold(text(L"Percentage by 10%"))),
+               separator(),
+               left_menu.Render()
+             ) | flex,
              // -------- Right Menu --------------
-             flex(
-               vbox(
-                 hcenter(bold(text(L"Percentage by 1%"))),
-                 separator(),
-                 right_menu.Render()
-               )
-             ),
-             flex()
+             vbox(
+               hcenter(bold(text(L"Percentage by 1%"))),
+               separator(),
+               right_menu.Render()
+             ) | flex,
+             filler()
            ),
            separator(),
            // -------- Bottom panel --------------
-           flex(vbox(
+           vbox(
              hbox(text(L" gauge : "), gauge(sum/100.0)),
              hbox(text(L"  text : "), text(to_wstring(std::to_string(sum) + " %")))
-           ))
+           ) | flex
          )
        );
    }
@@ -70,7 +66,7 @@ class MyComponent : ComponentHorizontal {
 
 int main(int argc, const char *argv[])
 {
-  ftxui::ScreenInteractive screen(60,18);
+  auto screen = ftxui::ScreenInteractive::TerminalOutput();
   MyComponent component(screen.delegate());
   component.on_enter = screen.ExitLoopClosure();
   screen.Loop();
diff --git a/examples/component/menu_style.cpp b/examples/component/menu_style.cpp
index f49baf623be90ac5101bf087937529fd7649fb0d..342e2e9f9743c9fc0c84fb5481ec912513b2eebd 100644
--- a/examples/component/menu_style.cpp
+++ b/examples/component/menu_style.cpp
@@ -33,7 +33,7 @@ class MyComponent : ComponentHorizontal {
      }
 
      menu_2.selected_style = color(Color::Blue);
-     menu_2.active_style = compose(bold, color(Color::Blue));
+     menu_2.active_style = bold | color(Color::Blue);
 
      menu_3.selected_style = color(Color::Blue);
      menu_3.active_style = bgcolor(Color::Blue);
@@ -45,9 +45,9 @@ class MyComponent : ComponentHorizontal {
      menu_5.selected_style = bgcolor(Color::Yellow);
      menu_5.active_style = bgcolor(Color::Red);
 
-     menu_6.normal_style = compose(dim, color(Color::Blue));
-     menu_6.selected_style = compose(nothing, color(Color::Blue));
-     menu_6.active_style = compose(bold, color(Color::Blue));
+     menu_6.normal_style = dim | color(Color::Blue);
+     menu_6.selected_style = color(Color::Blue);
+     menu_6.active_style = bold | color(Color::Blue);
 
      Focus(&menu_1);
    }
@@ -63,24 +63,21 @@ class MyComponent : ComponentHorizontal {
 
    Element Render() override {
      return
-      vbox(
         hbox(
-          flex(frame(center(text(L" menu_1 ")), menu_1.Render())),
-          flex(frame(center(text(L" menu_2 ")), menu_2.Render())),
-          flex(frame(center(text(L" menu_3 ")), menu_3.Render()))
-        ),
-        hbox(
-          flex(frame(center(text(L" menu_4 ")), menu_4.Render())),
-          flex(frame(center(text(L" menu_5 ")), menu_5.Render())),
-          flex(frame(center(text(L" menu_6 ")), menu_6.Render()))
-        )
-      );
+          menu_1.Render() | flex, separator(),
+          menu_2.Render() | flex, separator(),
+          menu_3.Render() | flex, separator(),
+          menu_4.Render() | flex, separator(),
+          menu_5.Render() | flex, separator(),
+          menu_6.Render() | flex
+        ) | frame;
    }
 };
 
 int main(int argc, const char *argv[])
 {
-  ftxui::ScreenInteractive screen(90,14);
+  //auto screen = ftxui::ScreenInteractive::TerminalOutput();
+  auto screen = ftxui::ScreenInteractive::Fullscreen();
   MyComponent component(screen.delegate());
   component.on_enter = screen.ExitLoopClosure();
   screen.Loop();
diff --git a/examples/component/tab.cpp b/examples/component/tab.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..228aaa40379efdd14bf399df15db095d4656e324
--- /dev/null
+++ b/examples/component/tab.cpp
@@ -0,0 +1,46 @@
+#include <iostream>
+#include <thread>
+
+#include "ftxui/component/component_vertical.hpp"
+#include "ftxui/component/toggle.hpp"
+#include "ftxui/component/menu.hpp"
+#include "ftxui/screen_interactive.hpp"
+#include "ftxui/util/string.hpp"
+
+using namespace ftxui;
+using namespace ftxui::component;
+using namespace ftxui::dom;
+
+class MyComponent : ComponentVertical {
+  public:
+   MyComponent(ftxui::component::Delegate* delegate)
+       : ComponentVertical(delegate),
+         toggle(delegate->NewChild()),
+         menu(delegate->NewChild()) {
+
+     toggle.options = {L" left ", L" middle ", L" end "};
+     menu.entries = {L" top ", L" middle ", L" bottom "};
+     Focus(&toggle);
+   }
+
+   std::function<void()> on_enter = [](){};
+  private:
+   Toggle toggle;
+   Menu menu;
+
+   Element Render() override {
+     return
+       vbox(
+        hbox(frame(toggle.Render()), filler()),
+        frame(menu.Render()));
+   }
+};
+
+ 
+int main(int argc, const char *argv[])
+{
+  auto screen = ftxui::ScreenInteractive::TerminalOutput();
+  MyComponent component(screen.delegate());
+  component.on_enter = screen.ExitLoopClosure();
+  screen.Loop();
+}
diff --git a/examples/component/toggle.cpp b/examples/component/toggle.cpp
index 127cb8f7fa4ccb42957a6ef634e17b0fef1533eb..8a6d0fd858dccac24dd90dd1f9519f54686bcc06 100644
--- a/examples/component/toggle.cpp
+++ b/examples/component/toggle.cpp
@@ -62,7 +62,7 @@ class MyComponent : ComponentVertical {
 };
 
 int main(int argc, const char* argv[]) {
-  ftxui::ScreenInteractive screen(70,7);
+  auto screen = ftxui::ScreenInteractive::TerminalOutput();
   MyComponent component(screen.delegate());
   component.on_enter = screen.ExitLoopClosure();
   screen.Loop();
diff --git a/examples/dom/CMakeLists.txt b/examples/dom/CMakeLists.txt
index 6d1bbb4b2b6a115fe53e28e97bffe9f4fd28af5f..7a4ff10f50d1bf27a845d53dbed5e24459a93692 100644
--- a/examples/dom/CMakeLists.txt
+++ b/examples/dom/CMakeLists.txt
@@ -2,5 +2,6 @@ example(color)
 example(dbox)
 example(frame)
 example(gauge)
+example(package_manager)
 example(separator)
 example(vbox_hbox)
diff --git a/examples/dom/color.cpp b/examples/dom/color.cpp
index 5eb429ca31c20b6746ac5841eba106707f338730..d8f80651e1acba4481e41625cd4201b12aeb88d3 100644
--- a/examples/dom/color.cpp
+++ b/examples/dom/color.cpp
@@ -46,7 +46,7 @@ int main(int argc, const char *argv[])
         bgcolor(Color::Yellow, text(L"Yellow")),
         bgcolor(Color::YellowLight, text(L"YellowLight"))
       ),
-      flex()
+      filler()
     );
 
   auto screen = ftxui::Screen::TerminalOutput(document);
diff --git a/examples/dom/frame.cpp b/examples/dom/frame.cpp
index 329d0041d6db719e8bce1d1795536c246b6def2b..52ec6df817778a86af96d4bbfa133f7e518ef34c 100644
--- a/examples/dom/frame.cpp
+++ b/examples/dom/frame.cpp
@@ -10,7 +10,7 @@ int main(int argc, const char *argv[])
   using namespace ftxui::dom;
 	auto document =
 		hbox(
-			frame(hcenter(text(L" main frame ")),
+			window(hcenter(text(L" main frame ")),
 				vbox(
 					text(L"Line 1"),
 					text(L"Line 2"),
@@ -23,14 +23,14 @@ int main(int argc, const char *argv[])
 						)
 					),
 					hbox(
-						frame(text(L"frame 2"),
+						window(text(L"frame 2"),
 							vbox(
 								text(L"Line 4"),
 								text(L"Line 5"),
 								text(L"Line 6")
 							)
 						),
-						frame(text(L"frame 3"),
+						window(text(L"frame 3"),
 							vbox(
 								text(L"Line 7"),
 								text(L"Line 8"),
@@ -41,7 +41,7 @@ int main(int argc, const char *argv[])
 					text(L"footer footer footer footer footer")
 				)
 			),
-			flex()
+			filler()
 		);
   auto screen = ftxui::Screen::TerminalOutput(document);
   Render(screen, document.get());
diff --git a/examples/dom/gauge.cpp b/examples/dom/gauge.cpp
index d1bee62b49abb459a3df7fc6e8db5bcecbe4b227..54ea3ae4f082522d6a528e7ad68c9c8efcc8602e 100644
--- a/examples/dom/gauge.cpp
+++ b/examples/dom/gauge.cpp
@@ -14,7 +14,7 @@ int main(int argc, const char *argv[])
     auto document =
         hbox(
           text(L"downloading:"),
-          flex(gauge(percentage)),
+          gauge(percentage) | flex,
           text(L" " + data_downloaded)
         );
     auto screen = ftxui::Screen(100, 1);
diff --git a/examples/dom/package_manager.cpp b/examples/dom/package_manager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2ba500935a770f7d7200969baccc6852a7518d53
--- /dev/null
+++ b/examples/dom/package_manager.cpp
@@ -0,0 +1,123 @@
+#include <chrono>
+#include <iostream>
+#include <thread>
+
+#include "ftxui/screen.hpp"
+#include "ftxui/dom/elements.hpp"
+#include "ftxui/util/string.hpp"
+#include <list>
+#include <vector>
+
+using namespace ftxui;
+using namespace ftxui::dom;
+
+int main(int argc, const char *argv[])
+{
+  struct Task {
+    std::wstring name;
+    int number_of_threads;
+    int downloaded;
+    int size;
+  };
+
+  std::list<Task> remaining_tasks = {
+    {L"contact server       "  , 10 , 0 , 6*25} ,
+    {L"download index.html  "  , 10 , 0 , 9*25} ,
+    {L"download script.js   "  , 1 , 0 , 3*25} ,
+    {L"download style.js    "  , 1 , 0 , 4*25} ,
+    {L"download image.png   "  , 1 , 0 , 5*25}  ,
+    {L"download big_1.png   "  , 1 , 0 , 30*25}  ,
+    {L"download icon_1.png  "  , 1 , 0 , 7*25}  ,
+    {L"download icon_2.png  "  , 1 , 0 , 8*25}  ,
+    {L"download big_2.png   "  , 1 , 0 , 30*25}  ,
+    {L"download small_1.png "  , 1 , 0 , 10*25}  ,
+    {L"download small_2.png "  , 1 , 0 , 11*25}  ,
+    {L"download small_3.png "  , 1 , 0 , 12*25}  ,
+  };
+
+  std::list<Task> displayed_task;
+
+  int remaining_threads = 12;
+  std::string reset_position;
+
+  int nb_queued = remaining_tasks.size();
+  int nb_active = 0;
+  int nb_done = 0;
+
+  auto to_text = [](int number) {
+    std::wstring t = to_wstring(std::to_string(number));
+    while(t.size() < 3)
+      t = L" " + t;
+    return text(t);
+  };
+  
+  for(;;) {
+    std::vector<Element> entries;
+    for(auto& task : displayed_task) {
+      auto style = (task.downloaded == task.size) ? dim : bold;
+      entries.push_back(
+        hbox(
+          text(task.name) | style,
+          separator(),
+          to_text(task.downloaded),
+          text(L"/"),
+          to_text(task.size),
+          separator(),
+          gauge(task.downloaded / float(task.size))
+        )
+      );
+    }
+
+    auto document =
+      vbox(
+        window(text(L" Task "),
+          vbox(std::move(entries))
+        ),
+        hbox(
+          window(text(L" Summary "),
+            vbox(
+              hbox(text(L"- done:   "), to_text(nb_done) | bold) | color(Color::Green),
+              hbox(text(L"- active: "), to_text(nb_active) | bold ) | color(Color::RedLight),
+              hbox(text(L"- queue:  "), to_text(nb_queued) | bold) | color(Color::Red)
+            )
+          )
+        )
+      );
+
+    // Draw.
+    //if (step != 0) screen.Clear();
+    auto screen = ftxui::Screen::TerminalOutput(document);
+    Render(screen, document.get());
+    std::cout << reset_position << screen.ToString() << std::flush;
+    reset_position = screen.ResetPosition();
+
+    // Simulate time.
+    using namespace std::chrono_literals;
+    std::this_thread::sleep_for(0.01s);
+
+    if (nb_active + nb_queued == 0)
+      break;
+
+    // Update the model.
+    for(auto& task : displayed_task) {
+      if (task.downloaded != task.size) {
+        task.downloaded++;
+      } else if (task.number_of_threads) {
+        remaining_threads += task.number_of_threads;
+        task.number_of_threads = 0;
+        nb_active--;
+        nb_done++;
+      }
+    }
+
+    if (remaining_tasks.size() &&
+        remaining_tasks.front().number_of_threads <= remaining_threads) {
+      remaining_threads -= remaining_tasks.front().number_of_threads;
+      displayed_task.push_back(remaining_tasks.front());
+      remaining_tasks.pop_front();
+      nb_queued--;
+      nb_active++;
+    }
+  }
+  std::cout << std::endl;
+}
diff --git a/examples/dom/separator.cpp b/examples/dom/separator.cpp
index 79f1f9afc7a20c0b6a89f1871cc60d9a7af03ffc..d25a14e8db9c8ce7b6147f147a99106c4ecd61b0 100644
--- a/examples/dom/separator.cpp
+++ b/examples/dom/separator.cpp
@@ -10,7 +10,7 @@ int main(int argc, const char *argv[])
       text(L"left-column"),
       separator(),
       flex(vbox(
-        flex(center(text(L"right-column"))),
+        center(text(L"right-column")) | flex,
         separator(),
         center(text(L"bottom-column"))
       ))
diff --git a/examples/dom/vbox_hbox.cpp b/examples/dom/vbox_hbox.cpp
index 77bdc35806e085658a75f890024295171aac7bcd..281f791a9fda7ea9e5625a0bfd4779a16a554f5a 100644
--- a/examples/dom/vbox_hbox.cpp
+++ b/examples/dom/vbox_hbox.cpp
@@ -9,21 +9,21 @@ int main(int argc, const char *argv[])
     vbox(
       hbox(
         text(L"north-west"),
-        flex(),
+        filler(),
         text(L"north-east")
       ),
-      flex(),
+      filler(),
       hbox(
         hbox(
-          flex(),
+          filler(),
           text(L"center"),
-          flex()
+          filler()
         )
       ),
-      flex(),
+      filler(),
       hbox(
         text(L"south-west"),
-        flex(),
+        filler(),
         text(L"south-east")
       )
     );
diff --git a/examples/print_key_press.cpp b/examples/print_key_press.cpp
index eb5e927c67b6f19bd791958f096e86d9030146dd..6bdf7f7e9676a1c9d0172d518a77e5b77cad4ed6 100644
--- a/examples/print_key_press.cpp
+++ b/examples/print_key_press.cpp
@@ -42,7 +42,7 @@ class DrawKey : public ftxui::component::Component {
 };
 
 int main(int argc, const char* argv[]) {
-  ftxui::ScreenInteractive screen(80,10);
+  auto screen = ftxui::ScreenInteractive::FixedSize(80,10);
   DrawKey draw_key(screen.delegate());
   screen.Loop();
 }
diff --git a/ftxui/include/ftxui/README.md b/ftxui/include/ftxui/README.md
index 0ad8ad1bb3ec5d7a0dfb0d7338a3ae5fea6eec8a..d1d2855c64e9ccf1fe641e5a02d579ecf5e98a27 100644
--- a/ftxui/include/ftxui/README.md
+++ b/ftxui/include/ftxui/README.md
@@ -22,7 +22,7 @@
 ## Level 3: ftxui::component::Component
   A hierarchical set of component. A component render itself by producing
   ftxui::dom::Node in Component::Render().
-  
+
   Some component can handle events:
     * keyboard
     * mouse
diff --git a/ftxui/include/ftxui/dom/elements.hpp b/ftxui/include/ftxui/dom/elements.hpp
index d646f248b6c6878bd780d9bae9bc09f78220c504..6609fd7c2f32e093e87c761328d153b6ae0ca62c 100644
--- a/ftxui/include/ftxui/dom/elements.hpp
+++ b/ftxui/include/ftxui/dom/elements.hpp
@@ -18,17 +18,17 @@ using Children = std::vector<Child>;
 Element vbox(Children);
 Element hbox(Children);
 Element dbox(Children);
-Element flex();
+Element filler();
 Element flex(Element);
 
 // --- Widget --
 Element text(std::wstring text);
 Element separator();
 Element gauge(float ratio);
-Element frame(Child);
-Element frame(Child title, Child content);
+Element frame(Element);
+Element window(Child title, Child content);
 
-// -- Style ---
+// -- Decorator ---
 Element bold(Element);
 Element dim(Element);
 Element inverted(Element);
@@ -46,8 +46,13 @@ Element center(Element);
 
 // --- Util ---
 Element nothing(Element element);
-Decorator compose(Decorator, Decorator);
 
+// Pipe elements into decorator togethers.
+// Examples: text("ftxui") | bold | underlined;
+Element operator|(Element, Decorator);
+Decorator operator|(Decorator, Decorator);
+
+// Make container able to take several children.
 template <class... Args>
 Children unpack(Args... args) {
   Children vec;
@@ -55,20 +60,15 @@ Children unpack(Args... args) {
   return vec;
 }
 
-template <class... Args>
-Element vbox(Args... children) {
-  return vbox(unpack(std::forward<Args>(children)...));
-}
-
-template <class... Args>
-Element hbox(Args... children) {
-  return hbox(unpack(std::forward<Args>(children)...));
-}
+#define TAKE_ANY_ARGS(container) \
+  template <class... Args> \
+  Element container(Args... children) { \
+    return container(unpack(std::forward<Args>(children)...)); \
+  } \
 
-template <class... Args>
-Element dbox(Args... children) {
-  return dbox(unpack(std::forward<Args>(children)...));
-}
+TAKE_ANY_ARGS(vbox)
+TAKE_ANY_ARGS(hbox)
+TAKE_ANY_ARGS(dbox)
 
 };  // namespace dom
 };  // namespace ftxui
diff --git a/ftxui/include/ftxui/screen.hpp b/ftxui/include/ftxui/screen.hpp
index f01e410e7fde8d099cca95df3c0a1304cda4999e..6a858b5263e2ec3a56a6a7254c3e397c3f695945 100644
--- a/ftxui/include/ftxui/screen.hpp
+++ b/ftxui/include/ftxui/screen.hpp
@@ -49,7 +49,7 @@ class Screen {
   // Fill with space.
   void Clear();
 
- private:
+ protected:
   size_t dimx_;
   size_t dimy_;
   std::vector<std::vector<Pixel>> pixels_;
diff --git a/ftxui/include/ftxui/screen_interactive.hpp b/ftxui/include/ftxui/screen_interactive.hpp
index 1acf9e1a949efcfade4e72ca089e4d20499ba5c1..6ae80be9b4e237f7376c31145205af2b8b62107f 100644
--- a/ftxui/include/ftxui/screen_interactive.hpp
+++ b/ftxui/include/ftxui/screen_interactive.hpp
@@ -14,7 +14,10 @@ namespace component {
 
 class ScreenInteractive : public Screen {
   public:
-    ScreenInteractive(size_t dimx, size_t dimy);
+    static ScreenInteractive FixedSize(size_t dimx, size_t dimy);
+    static ScreenInteractive Fullscreen();
+    static ScreenInteractive TerminalOutput();
+
     ~ScreenInteractive();
     component::Delegate* delegate();
     void Loop();
@@ -27,6 +30,15 @@ class ScreenInteractive : public Screen {
 	 void Clear();
 	 void Draw();
 	 bool quit_ = false;
+
+   enum class Dimension {
+     Fixed,
+     TerminalOutput,
+     Fullscreen,
+   };
+   Dimension dimension_ = Dimension::Fixed;
+
+   ScreenInteractive(size_t dimx, size_t dimy, Dimension dimension);
 };
 
 }  // namespace ftxui
diff --git a/ftxui/src/ftxui/component/input.cpp b/ftxui/src/ftxui/component/input.cpp
index 77e53d66d649b0f57fe8bdbfbc8287f128119ce6..adfd82aa93b278c314d07cfec5da5b2649762ec7 100644
--- a/ftxui/src/ftxui/component/input.cpp
+++ b/ftxui/src/ftxui/component/input.cpp
@@ -15,14 +15,14 @@ dom::Element Input::Render() {
   // Placeholder.
   if (content.size() == 0) {
     if (is_focused)
-      return flex(inverted(dim(text(placeholder))));
+      return text(placeholder) | dim | inverted | flex;
     else
-      return flex(dim(text(placeholder)));
+      return text(placeholder) | dim | flex;
   }
 
   // Not focused.
   if (!is_focused)
-    return flex(text(content));
+    return text(content) | flex;
 
   std::wstring part_before_cursor = content.substr(0,cursor_position);
   std::wstring part_at_cursor = cursor_position < (int)content.size()
@@ -31,11 +31,12 @@ dom::Element Input::Render() {
   std::wstring part_after_cursor = cursor_position < (int)content.size() - 1
                                        ? content.substr(cursor_position + 1)
                                        : L"";
-  return flex(inverted(hbox(             //
-      text(part_before_cursor),          //
-      underlined(text(part_at_cursor)),  //
-      text(part_after_cursor)            //
-      )));                               //
+  return
+    hbox(
+      text(part_before_cursor),
+      text(part_at_cursor) | underlined,
+      text(part_after_cursor)
+    ) | flex | inverted;
 }
 bool Input::OnEvent(Event event) {
   std::wstring c;
diff --git a/ftxui/src/ftxui/component/toggle.cpp b/ftxui/src/ftxui/component/toggle.cpp
index ed8784f600c2d801e0ed9cdce5fd4e97ae59d3b6..39f12e7061f8125092bd9a19c7fcb031dccd7b4f 100644
--- a/ftxui/src/ftxui/component/toggle.cpp
+++ b/ftxui/src/ftxui/component/toggle.cpp
@@ -10,18 +10,16 @@ dom::Element Toggle::Render() {
   auto highlight = Focused() ? inverted : bold;
 
   Children children;
-  children.push_back(text(L"["));
 
   for(size_t i = 0; i<options.size(); ++i) {
     // Separator.
     if (i != 0)
-      children.push_back(text(L"|"));
+      children.push_back(separator());
 
     // Entry.
     auto style = i == activated ? highlight : dim;
     children.push_back(style(text(options[i])));
   }
-  children.push_back(text(L"]"));
   return hbox(std::move(children));
 }
 
diff --git a/ftxui/src/ftxui/dom/bold.cpp b/ftxui/src/ftxui/dom/bold.cpp
index 902502010b573561487c4bde7aa5f00ab0fd986f..49c214a3eb9aa2aa9168227291f0a12d0b688605 100644
--- a/ftxui/src/ftxui/dom/bold.cpp
+++ b/ftxui/src/ftxui/dom/bold.cpp
@@ -10,12 +10,12 @@ class Bold : public NodeDecorator {
   ~Bold() override {}
 
   void Render(Screen& screen) override {
-    Node::Render(screen);
     for (int y = box_.top; y <= box_.bottom; ++y) {
       for (int x = box_.left; x <= box_.right; ++x) {
         screen.PixelAt(x,y).bold = true; 
       }
     }
+    Node::Render(screen);
   }
 };
 
diff --git a/ftxui/src/ftxui/dom/color.cpp b/ftxui/src/ftxui/dom/color.cpp
index 984c616be0916b7dcaa583031691f481624acd20..cf63704e207f17a3ecd5180e65c5fa684ea85735 100644
--- a/ftxui/src/ftxui/dom/color.cpp
+++ b/ftxui/src/ftxui/dom/color.cpp
@@ -10,12 +10,12 @@ class BgColor : public NodeDecorator {
       : NodeDecorator(std::move(children)), color_(color) {}
 
   void Render(Screen& screen) override {
-    NodeDecorator::Render(screen);
     for (int y = box_.top; y <= box_.bottom; ++y) {
       for (int x = box_.left; x <= box_.right; ++x) {
         screen.PixelAt(x, y).background_color = color_;
       }
     }
+    NodeDecorator::Render(screen);
   }
 
   Color color_;
@@ -28,12 +28,12 @@ class FgColor : public NodeDecorator {
   ~FgColor() override {}
 
   void Render(Screen& screen) override {
-    NodeDecorator::Render(screen);
     for (int y = box_.top; y <= box_.bottom; ++y) {
       for (int x = box_.left; x <= box_.right; ++x) {
         screen.PixelAt(x, y).foreground_color = color_;
       }
     }
+    NodeDecorator::Render(screen);
   }
 
   Color color_;
diff --git a/ftxui/src/ftxui/dom/composite_decorator.cpp b/ftxui/src/ftxui/dom/composite_decorator.cpp
index cedc328136a736a21abb3db9d8bda09b60e7837c..2f64105e9a3b69020e28e3beec3323162215df2c 100644
--- a/ftxui/src/ftxui/dom/composite_decorator.cpp
+++ b/ftxui/src/ftxui/dom/composite_decorator.cpp
@@ -5,11 +5,11 @@ namespace ftxui {
 namespace dom {
 
 std::unique_ptr<Node> hcenter(Element child) {
-  return hbox(flex(), std::move(child), flex());
+  return hbox(filler(), std::move(child), filler());
 }
 
 std::unique_ptr<Node> vcenter(Element child) {
-  return vbox(flex(), std::move(child), flex());
+  return vbox(filler(), std::move(child), filler());
 }
 
 std::unique_ptr<Node> center(Element child) {
diff --git a/ftxui/src/ftxui/dom/flex.cpp b/ftxui/src/ftxui/dom/flex.cpp
index 9684dff72718a314aade2cff48fdc15076e56f44..7741a7794e08f64f2923c2695325bf9029ba223e 100644
--- a/ftxui/src/ftxui/dom/flex.cpp
+++ b/ftxui/src/ftxui/dom/flex.cpp
@@ -27,7 +27,7 @@ class Flex : public Node {
   }
 };
 
-std::unique_ptr<Node> flex() {
+std::unique_ptr<Node> filler() {
   return std::make_unique<Flex>();
 }
 
diff --git a/ftxui/src/ftxui/dom/frame.cpp b/ftxui/src/ftxui/dom/frame.cpp
index 6112b701ed9d15176e168c44b1d5eb0600219826..1bbe056f7c709fcaf5533edb7c4cb6cf7e2fac78 100644
--- a/ftxui/src/ftxui/dom/frame.cpp
+++ b/ftxui/src/ftxui/dom/frame.cpp
@@ -84,9 +84,15 @@ std::unique_ptr<Node> frame(Child child) {
   return std::make_unique<Frame>(unpack(std::move(child)));
 }
 
-std::unique_ptr<Node> frame(Child title, Child content) {
+std::unique_ptr<Node> window(Child title, Child content) {
   return std::make_unique<Frame>(unpack(std::move(content), std::move(title)));
 }
 
+Decorator boxed() {
+  return [](Child child) {
+    return frame(std::move(child));
+  };
+}
+
 };  // namespace dom
 };  // namespace ftxui
diff --git a/ftxui/src/ftxui/dom/hbox_test.cpp b/ftxui/src/ftxui/dom/hbox_test.cpp
index 83f775bd906cd274e62751571de2a2858af69ce1..859852efd168ed5164c71e7bb72ce235d2c37aa8 100644
--- a/ftxui/src/ftxui/dom/hbox_test.cpp
+++ b/ftxui/src/ftxui/dom/hbox_test.cpp
@@ -62,7 +62,7 @@ TEST(HBoxTest, ScreenBigger2) {
 TEST(HBoxTest, ScreenSmaller1Flex) {
   auto root = hbox(
     text(L"text_1"),
-    flex(),
+    filler(),
     text(L"text_2")
   );
   Screen screen(11,1);
@@ -74,7 +74,7 @@ TEST(HBoxTest, ScreenSmaller1Flex) {
 TEST(HBoxTest, ScreenSmaller2Flex) {
   auto root = hbox(
     text(L"text_1"),
-    flex(),
+    filler(),
     text(L"text_2")
   );
   Screen screen(10,1);
@@ -86,7 +86,7 @@ TEST(HBoxTest, ScreenSmaller2Flex) {
 TEST(HBoxTest, ScreenFitFlex) {
   auto root = hbox(
     text(L"text_1"),
-    flex(),
+    filler(),
     text(L"text_2")
   );
   Screen screen(12,1);
@@ -98,7 +98,7 @@ TEST(HBoxTest, ScreenFitFlex) {
 TEST(HBoxTest, ScreenBigger1Flex) {
   auto root = hbox(
     text(L"text_1"),
-    flex(),
+    filler(),
     text(L"text_2")
   );
   Screen screen(13,1);
@@ -110,7 +110,7 @@ TEST(HBoxTest, ScreenBigger1Flex) {
 TEST(HBoxTest, ScreenBigger2Flex) {
   auto root = hbox(
     text(L"text_1"),
-    flex(),
+    filler(),
     text(L"text_2")
   );
   Screen screen(14,1);
diff --git a/ftxui/src/ftxui/dom/separator.cpp b/ftxui/src/ftxui/dom/separator.cpp
index db22aeb1293ce309c7f936ddd11a12491bf68956..b298e06c23282fa0120d5a376505dd0a179e076c 100644
--- a/ftxui/src/ftxui/dom/separator.cpp
+++ b/ftxui/src/ftxui/dom/separator.cpp
@@ -19,7 +19,7 @@ class Separator : public Node {
     wchar_t c = U'+';
     if (is_line && !is_column)
       c = U'─';
-    else if (!is_line && is_column)
+    else
       c = U'│';
 
     for (int y = box_.top; y <= box_.bottom; ++y) {
diff --git a/ftxui/src/ftxui/dom/util.cpp b/ftxui/src/ftxui/dom/util.cpp
index 0e9468a5169c98fea0c879c170de9b76be4e33da..afdb3dec63c1bcd2dcee37ff8280ee57c72d5024 100644
--- a/ftxui/src/ftxui/dom/util.cpp
+++ b/ftxui/src/ftxui/dom/util.cpp
@@ -12,9 +12,17 @@ Decorator compose(Decorator a, Decorator b) {
     a = std::move(a),
     b = std::move(b)
   ](Element element) {
-    return a(b(std::move(element)));
+    return b(a(std::move(element)));
   };
 }
 
-};  // namespace dom
-};  // namespace ftxui
+Decorator operator|(Decorator a, Decorator b) {
+  return compose(a, b);
+}
+
+Element operator|(Element e, Decorator d) {
+  return d(std::move(e));
+}
+
+}  // namespace dom
+}  // namespace ftxui
diff --git a/ftxui/src/ftxui/dom/vbox_test.cpp b/ftxui/src/ftxui/dom/vbox_test.cpp
index 912c349109be4e669a936f48a8f02f14ca04df60..3e1ef4539d3d594cdbfbcc4b091760648e6290c8 100644
--- a/ftxui/src/ftxui/dom/vbox_test.cpp
+++ b/ftxui/src/ftxui/dom/vbox_test.cpp
@@ -37,7 +37,7 @@ TEST(VBoxTest, ScreenBigger2) {
 }
 
 TEST(VBoxTest, ScreenSmaller1Flex) {
-  auto root = vbox(text(L"text_1"), flex(), text(L"text_2"));
+  auto root = vbox(text(L"text_1"), filler(), text(L"text_2"));
   Screen screen(6, 1);
   Render(screen, root.get());
 
@@ -45,7 +45,7 @@ TEST(VBoxTest, ScreenSmaller1Flex) {
 }
 
 TEST(VBoxTest, ScreenFitFlex) {
-  auto root = vbox(text(L"text_1"), flex(), text(L"text_2"));
+  auto root = vbox(text(L"text_1"), filler(), text(L"text_2"));
   Screen screen(6, 2);
   Render(screen, root.get());
 
@@ -53,14 +53,14 @@ TEST(VBoxTest, ScreenFitFlex) {
 }
 
 TEST(VBoxTest, ScreenBigger1Flex) {
-  auto root = vbox(text(L"text_1"), flex(), text(L"text_2"));
+  auto root = vbox(text(L"text_1"), filler(), text(L"text_2"));
   Screen screen(6, 3);
   Render(screen, root.get());
 
   EXPECT_EQ("text_1\n      \ntext_2", screen.ToString());
 }
 TEST(VBoxTest, ScreenBigger2Flex) {
-  auto root = vbox(text(L"text_1"), flex(), text(L"text_2"));
+  auto root = vbox(text(L"text_1"), filler(), text(L"text_2"));
   Screen screen(6, 4);
   Render(screen, root.get());
 
diff --git a/ftxui/src/ftxui/screen.cpp b/ftxui/src/ftxui/screen.cpp
index c2e051662fa2f5711affb1610bb683dae202b9f9..27cc923fd527fe4f991c78bf7186e453003cd82a 100644
--- a/ftxui/src/ftxui/screen.cpp
+++ b/ftxui/src/ftxui/screen.cpp
@@ -12,28 +12,19 @@ Screen::Screen(size_t dimx, size_t dimy)
 
 void UpdatePixelStyle(std::wstringstream& ss, Pixel& previous, Pixel& next) {
   if (next.bold != previous.bold)
-    ss << (next.bold ? L"\e[1m" : L"\e[0m");
-
-  if (next.inverted != previous.inverted)
-    ss << (next.inverted ? L"\e[7m" : L"\e[27m");
-
-  if (next.underlined != previous.underlined)
-    ss << (next.underlined ? L"\e[4m" : L"\e[24m");
-
+    ss << (next.bold ? L"\e[1m" : L"\e[22m"); // Can't use 21 here.
   if (next.dim != previous.dim)
     ss << (next.dim ? L"\e[2m" : L"\e[22m");
-
+  if (next.underlined != previous.underlined)
+    ss << (next.underlined ? L"\e[4m" : L"\e[24m");
   if (next.blink != previous.blink)
     ss << (next.blink ? L"\e[5m" : L"\e[25m");
-
-  if (next.foreground_color != previous.foreground_color) {
-    ss << L"\e[" + to_wstring(std::to_string((uint8_t)next.foreground_color)) +
-              L"m";
-  }
-  if (next.background_color != previous.background_color) {
-    ss << L"\e[" +
-              to_wstring(std::to_string(10 + (uint8_t)next.background_color)) +
-              L"m";
+  if (next.inverted != previous.inverted)
+    ss << (next.inverted ? L"\e[7m" : L"\e[27m");
+  if (next.foreground_color != previous.foreground_color ||
+      next.background_color != previous.background_color) {
+    ss << L"\e[" + to_wstring(std::to_string((uint8_t)next.foreground_color)) + L"m";
+    ss << L"\e[" + to_wstring(std::to_string(10 + (uint8_t)next.background_color)) + L"m";
   }
 
   previous = next;
@@ -49,8 +40,11 @@ std::string Screen::ToString() {
       UpdatePixelStyle(ss, previous_pixel, pixels_[y][x]);
       ss << pixels_[y][x].character;
     }
+
     if (y + 1 < dimy_)
       ss << '\n';
+    Pixel final_pixel;
+    UpdatePixelStyle(ss, previous_pixel, final_pixel);
   }
 
   return to_string(ss.str());
diff --git a/ftxui/src/ftxui/screen_interactive.cpp b/ftxui/src/ftxui/screen_interactive.cpp
index 0ffd1fd527d5cff0f9bb001dfa44fcd68d62e319..8ba98fb1b1a1860b2cd5a7a86dbfa8adc5bab22a 100644
--- a/ftxui/src/ftxui/screen_interactive.cpp
+++ b/ftxui/src/ftxui/screen_interactive.cpp
@@ -1,6 +1,8 @@
 #include "ftxui/screen_interactive.hpp"
+
 #include "ftxui/component/component.hpp"
 #include "ftxui/component/delegate.hpp"
+#include "ftxui/terminal.hpp"
 #include <iostream>
 #include <stdio.h>
 #include <termios.h>
@@ -86,10 +88,27 @@ class ScreenInteractive::Delegate : public component::Delegate {
   component::Component* component() override { return component_; }
 };
 
-ScreenInteractive::ScreenInteractive(size_t dimx, size_t dimy)
-    : Screen(dimx, dimy), delegate_(new Delegate) {}
+ScreenInteractive::ScreenInteractive(size_t dimx,
+                                     size_t dimy,
+                                     Dimension dimension)
+    : Screen(dimx, dimy), delegate_(new Delegate), dimension_(dimension) {}
 ScreenInteractive::~ScreenInteractive() {}
 
+// static
+ScreenInteractive ScreenInteractive::FixedSize(size_t dimx, size_t dimy) {
+  return ScreenInteractive(dimx, dimy, Dimension::Fixed);
+}
+
+// static
+ScreenInteractive ScreenInteractive::Fullscreen() {
+  return ScreenInteractive(0, 0, Dimension::Fullscreen);
+}
+
+// static
+ScreenInteractive ScreenInteractive::TerminalOutput() {
+  return ScreenInteractive(0, 0, Dimension::TerminalOutput);
+}
+
 void ScreenInteractive::Loop() {
   std::cout << "\033[?9h";    /* Send Mouse Row & Column on Button Press */
   std::cout << "\033[?1000h"; /* Send Mouse X & Y on button press and release */
@@ -110,14 +129,12 @@ void ScreenInteractive::Loop() {
   tcsetattr(STDIN_FILENO, TCSANOW, &terminal_configuration_new);
 
   Draw();
-  while (!quit_) {
+  while(!quit_) {
     delegate_->OnEvent(GetEvent());
-
     Clear();
     Draw();
-  }
-  std::cout << std::endl;
-  //Clear();
+  } while(!quit_);
+  //std::cout << std::endl;
 
   // Restore the old terminal configuration.
   tcsetattr(STDIN_FILENO, TCSANOW, &terminal_configuration_old);
@@ -125,6 +142,29 @@ void ScreenInteractive::Loop() {
 
 void ScreenInteractive::Draw() {
   auto document = delegate_->component()->Render();
+  size_t dimx;
+  size_t dimy;
+  switch(dimension_) {
+    case Dimension::Fixed:
+      break;
+    case Dimension::TerminalOutput:
+      document->ComputeRequirement();
+      dimx = Terminal::Size().dimx;
+      dimy = document->requirement().min.y;
+      break;
+    case Dimension::Fullscreen:
+      document->ComputeRequirement();
+      dimx = Terminal::Size().dimx;
+      dimy = Terminal::Size().dimy;
+      break;
+  }
+
+  if (dimx != dimx_ || dimy != dimy_) {
+    dimx_ = dimx;
+    dimy_ = dimy;
+    pixels_ = std::vector<std::vector<Pixel>>(dimy, std::vector<Pixel>(dimx));
+  }
+
   Render(*this, document.get());
   std::cout << ToString() << std::flush;
 }