diff --git a/CHANGELOG.md b/CHANGELOG.md
index 046453356cd50c125cd10fc70ad277579cff023a..d76668523e1d753b343beb29361390a9480a1fe0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,10 @@ current (development)
 ### Component:
 - Feature: Add the `Modal` component.
 - Feature: `Slider` supports taking references for all its arguments.
+- Feature: `Slider` supports `SliderOption`. It supports:
+    - multiple directions.
+    - multiple colors.
+    - various values (value, min, max, increment).
 - Improvement: The `Menu` keeps the focus when an entry is selected with the
   mouse.
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b48bdeca65247f6ac7ead77d3162849f1e45ce26..2a884350950942e5c0ab25822f0ce215003aa455 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -132,10 +132,6 @@ target_link_libraries(component
   PUBLIC Threads::Threads
 )
 
-set_target_properties(screen PROPERTIES VERSION ${PROJECT_VERSION})
-set_target_properties(dom PROPERTIES VERSION ${PROJECT_VERSION})
-set_target_properties(component PROPERTIES VERSION ${PROJECT_VERSION})
-
 include(cmake/ftxui_set_options.cmake)
 ftxui_set_options(screen)
 ftxui_set_options(dom)
diff --git a/cmake/ftxui_set_options.cmake b/cmake/ftxui_set_options.cmake
index 1cefd5c3a97bbf3319680a66feaff01d9b6c8814..6fd7baf0b6f0e784ff07bf35ab4c91b22588d010 100644
--- a/cmake/ftxui_set_options.cmake
+++ b/cmake/ftxui_set_options.cmake
@@ -7,7 +7,11 @@ endif()
 
 
 function(ftxui_set_options library)
-  set_target_properties(${library} PROPERTIES OUTPUT_NAME "ftxui-${library}")
+  set_target_properties(${library} PROPERTIES
+    VERSION ${PROJECT_VERSION}
+    CXX_STANDARD 20
+    OUTPUT_NAME "ftxui-${library}"
+  )
 
   if(CLANG_TIDY_EXE AND FTXUI_CLANG_TIDY)
     set_target_properties(${library}
diff --git a/cmake/ftxui_test.cmake b/cmake/ftxui_test.cmake
index 7f4e237619ec246d967b7d7173dacb5d4e4968fc..5aabb2cba2f8393ffd81e16dda7d7e3b02dcc880 100644
--- a/cmake/ftxui_test.cmake
+++ b/cmake/ftxui_test.cmake
@@ -34,6 +34,7 @@ add_executable(tests
   src/ftxui/component/modal_test.cpp
   src/ftxui/component/radiobox_test.cpp
   src/ftxui/component/receiver_test.cpp
+  src/ftxui/component/slider_test.cpp
   src/ftxui/component/resizable_split_test.cpp
   src/ftxui/component/screen_interactive_test.cpp
   src/ftxui/component/terminal_input_parser_test.cpp
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 7b02d17e367655c41691c4a2c48f2d4e0e514c8e..016aa73ab0351490bc328f94937c9b840b1067db 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -4,6 +4,9 @@ function(example name)
   target_link_libraries(ftxui_example_${name} PUBLIC ${DIRECTORY_LIB})
   file(RELATIVE_PATH dir ${EXAMPLES_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
   set_property(GLOBAL APPEND PROPERTY FTXUI::EXAMPLES ${dir}/${name})
+  set_target_properties(ftxui_example_${name} PROPERTIES
+    CXX_STANDARD 20
+  )
 endfunction(example)
 
 add_subdirectory(component)
diff --git a/examples/component/CMakeLists.txt b/examples/component/CMakeLists.txt
index 3a5ef7007fa31cc285e653c7aee2c6b130579c07..e89111039690dbcec116ac73c7be52c95db2b52c 100644
--- a/examples/component/CMakeLists.txt
+++ b/examples/component/CMakeLists.txt
@@ -33,6 +33,7 @@ example(radiobox_in_frame)
 example(renderer)
 example(resizable_split)
 example(slider)
+example(slider_direction)
 example(slider_rgb)
 example(tab_horizontal)
 example(tab_vertical)
diff --git a/examples/component/slider_direction.cpp b/examples/component/slider_direction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1a0a39051b12edfe77174adf9ad376cb0fc7362c
--- /dev/null
+++ b/examples/component/slider_direction.cpp
@@ -0,0 +1,37 @@
+#include <array>                               // for array
+#include <cmath>                               // for sin
+#include <ftxui/component/component_base.hpp>  // for ComponentBase
+#include <ftxui/dom/elements.hpp>  // for size, GaugeDirection, GaugeDirection::Up, GREATER_THAN, HEIGHT
+#include <memory>  // for shared_ptr, __shared_ptr_access
+
+#include "ftxui/component/captured_mouse.hpp"  // for ftxui
+#include "ftxui/component/component.hpp"  // for Horizontal, Slider, operator|=
+#include "ftxui/component/screen_interactive.hpp"  // for ScreenInteractive
+
+using namespace ftxui;
+
+int main(int argc, const char* argv[]) {
+  auto screen = ScreenInteractive::TerminalOutput();
+  std::array<int, 30> values;
+  for (int i = 0; i < values.size(); ++i) {
+    values[i] = 50 + 20 * std::sin(i * 0.3);
+  }
+
+  auto layout_horizontal = Container::Horizontal({});
+  for (int i = 0; i < values.size(); ++i) {
+    layout_horizontal->Add(Slider<int>({
+        .value = &values[i],
+        .max = 100,
+        .increment = 5,
+        .direction = GaugeDirection::Up,
+    }));
+  }
+
+  layout_horizontal |= size(HEIGHT, GREATER_THAN, 20);
+
+  screen.Loop(layout_horizontal);
+}
+
+// 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/component.hpp b/include/ftxui/component/component.hpp
index fb8729d20e7c7d91441cdf75c0828e6cd490f7f0..80f48ed7e16dd725d2070877ef0fdeea5ee6b286 100644
--- a/include/ftxui/component/component.hpp
+++ b/include/ftxui/component/component.hpp
@@ -10,7 +10,7 @@
 #include "ftxui/component/component_base.hpp"  // for Component, Components
 #include "ftxui/component/component_options.hpp"  // for ButtonOption, CheckboxOption, MenuOption
 #include "ftxui/dom/elements.hpp"  // for Element
-#include "ftxui/util/ref.hpp"  // for Ref, ConstStringRef, ConstStringListRef, StringRef
+#include "ftxui/util/ref.hpp"  // for ConstRef, Ref, ConstStringRef, ConstStringListRef, StringRef
 
 namespace ftxui {
 struct ButtonOption;
@@ -82,6 +82,9 @@ Component Slider(ConstStringRef label,
                  ConstRef<long> min = 0l,
                  ConstRef<long> max = 100l,
                  ConstRef<long> increment = 5l);
+// General slider type without support for a `label`.
+template <typename T>  // T = {int, float, long}
+Component Slider(SliderOption<T> options = {});
 
 Component ResizableSplitLeft(Component main, Component back, int* main_size);
 Component ResizableSplitRight(Component main, Component back, int* main_size);
diff --git a/include/ftxui/component/component_options.hpp b/include/ftxui/component/component_options.hpp
index 776d35122e38a54479384889d0841c90226268ae..8863ff6a2939157288703386b89c1c4f81191f13 100644
--- a/include/ftxui/component/component_options.hpp
+++ b/include/ftxui/component/component_options.hpp
@@ -3,11 +3,11 @@
 
 #include <chrono>                         // for milliseconds
 #include <ftxui/component/animation.hpp>  // for Duration, QuadraticInOut, Function
-#include <ftxui/dom/elements.hpp>         // for Element
-#include <ftxui/util/ref.hpp>             // for Ref
-#include <functional>                     // for function
-#include <optional>                       // for optional
-#include <string>                         // for string
+#include <ftxui/dom/elements.hpp>  // for Element, GaugeDirection, GaugeDirection::Right
+#include <ftxui/util/ref.hpp>  // for Ref, ConstRef
+#include <functional>          // for function
+#include <optional>            // for optional
+#include <string>              // for string
 
 #include "ftxui/screen/color.hpp"  // for Color, Color::GrayDark, Color::White
 
@@ -164,6 +164,19 @@ struct RadioboxOption {
   Ref<int> focused_entry = 0;
 };
 
+// @brief Option for the `Slider` component.
+// @ingroup component
+template <typename T>
+struct SliderOption {
+  Ref<T> value;
+  ConstRef<T> min = T(0);
+  ConstRef<T> max = T(100);
+  ConstRef<T> increment = (max() - min()) / 20;
+  GaugeDirection direction = GaugeDirection::Right;
+  Color color_active = Color::White;
+  Color color_inactive = Color::GrayDark;
+};
+
 }  // namespace ftxui
 
 #endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP */
diff --git a/include/ftxui/screen/screen.hpp b/include/ftxui/screen/screen.hpp
index 21eb377645b57d54554bb89743ca3b5e6e367cb5..6ca7e5ae2b25efcecc598e1b696151535e141dc4 100644
--- a/include/ftxui/screen/screen.hpp
+++ b/include/ftxui/screen/screen.hpp
@@ -2,7 +2,7 @@
 #define FTXUI_SCREEN_SCREEN_HPP
 
 #include <memory>
-#include <string>  // for string, allocator, basic_string
+#include <string>  // for allocator, string, basic_string
 #include <vector>  // for vector
 
 #include "ftxui/screen/box.hpp"       // for Box
diff --git a/src/ftxui/component/animation.cpp b/src/ftxui/component/animation.cpp
index bba5783bb19b6bee8d7f1c70eedbcd90ddf7d3fa..db904ba25f750f5147e5e08402e2429a5a2dc2b2 100644
--- a/src/ftxui/component/animation.cpp
+++ b/src/ftxui/component/animation.cpp
@@ -1,4 +1,5 @@
 #include <cmath>    // IWYU pragma: keep
+#include <compare>  // for operator<=, operator>=, partial_ordering
 #include <ratio>    // for ratio
 #include <utility>  // for move
 
diff --git a/src/ftxui/component/checkbox.cpp b/src/ftxui/component/checkbox.cpp
index 9e7c35413dfe313fa1719ff632396a907fbaf921..39a2366aa04c2dde68bf6f2cdc3d80c57b012c42 100644
--- a/src/ftxui/component/checkbox.cpp
+++ b/src/ftxui/component/checkbox.cpp
@@ -1,14 +1,13 @@
 #include <functional>  // for function
-#include <memory>      // for shared_ptr
 #include <utility>     // for move
 
 #include "ftxui/component/captured_mouse.hpp"  // for CapturedMouse
-#include "ftxui/component/component.hpp"       // for Make, Component, Checkbox
-#include "ftxui/component/component_base.hpp"  // for ComponentBase
-#include "ftxui/component/component_options.hpp"  // for CheckboxOption
+#include "ftxui/component/component.hpp"       // for Make, Checkbox
+#include "ftxui/component/component_base.hpp"  // for Component, ComponentBase
+#include "ftxui/component/component_options.hpp"  // for CheckboxOption, EntryState
 #include "ftxui/component/event.hpp"              // for Event, Event::Return
 #include "ftxui/component/mouse.hpp"  // for Mouse, Mouse::Left, Mouse::Pressed
-#include "ftxui/dom/elements.hpp"  // for operator|, text, Element, hbox, reflect, focus, nothing, select
+#include "ftxui/dom/elements.hpp"  // for operator|, Element, reflect, focus, nothing, select
 #include "ftxui/screen/box.hpp"  // for Box
 #include "ftxui/util/ref.hpp"    // for Ref, ConstStringRef
 
diff --git a/src/ftxui/component/input.cpp b/src/ftxui/component/input.cpp
index 6883dc11a586c33dcce11ab22d5c7783ba960655..307cb6ca08907cf3ce0397a5b356b124596bde95 100644
--- a/src/ftxui/component/input.cpp
+++ b/src/ftxui/component/input.cpp
@@ -1,8 +1,7 @@
 #include <algorithm>   // for max, min
 #include <cstddef>     // for size_t
 #include <functional>  // for function
-#include <memory>      // for shared_ptr, allocator
-#include <string>      // for string, wstring
+#include <string>      // for string, allocator
 #include <utility>     // for move
 #include <vector>      // for vector
 
@@ -15,7 +14,7 @@
 #include "ftxui/component/screen_interactive.hpp"  // for Component
 #include "ftxui/dom/elements.hpp"  // for operator|, text, Element, reflect, inverted, Decorator, flex, focus, hbox, size, bold, dim, frame, select, EQUAL, HEIGHT
 #include "ftxui/screen/box.hpp"    // for Box
-#include "ftxui/screen/string.hpp"  // for GlyphPosition, GlyphCount, to_string, CellToGlyphIndex, to_wstring
+#include "ftxui/screen/string.hpp"  // for GlyphPosition, GlyphCount, CellToGlyphIndex
 #include "ftxui/screen/util.hpp"  // for clamp
 #include "ftxui/util/ref.hpp"     // for StringRef, Ref, ConstStringRef
 
diff --git a/src/ftxui/component/menu.cpp b/src/ftxui/component/menu.cpp
index df9d21138d86289043250120d3e105b79a142241..62cea4ffe86d07709260d662e0f153a656644dd8 100644
--- a/src/ftxui/component/menu.cpp
+++ b/src/ftxui/component/menu.cpp
@@ -464,7 +464,7 @@ class MenuBase : public ComponentBase {
   ConstStringListRef entries_;
   int* selected_;
   int selected_previous_ = *selected_;
-  int selected_focus_= *selected_;
+  int selected_focus_ = *selected_;
   Ref<MenuOption> option_;
 
   std::vector<Box> boxes_;
diff --git a/src/ftxui/component/radiobox.cpp b/src/ftxui/component/radiobox.cpp
index 41da88b91b0be7b3870ae597833be953ec273680..b7b0ff738872304cbf286fc5a0433165e5b197fc 100644
--- a/src/ftxui/component/radiobox.cpp
+++ b/src/ftxui/component/radiobox.cpp
@@ -1,6 +1,5 @@
-#include <algorithm>   // for max
 #include <functional>  // for function
-#include <memory>      // for shared_ptr, allocator_traits<>::value_type
+#include <memory>      // for allocator_traits<>::value_type
 #include <utility>     // for move
 #include <vector>      // for vector
 
diff --git a/src/ftxui/component/screen_interactive.cpp b/src/ftxui/component/screen_interactive.cpp
index d836ac270f6048b1e3c80c84f11a47724376ed78..e506f132c70d8a8b13bba864e9ae071e6923e125 100644
--- a/src/ftxui/component/screen_interactive.cpp
+++ b/src/ftxui/component/screen_interactive.cpp
@@ -1,6 +1,7 @@
-#include <algorithm>  // for copy, max, min
+#include <algorithm>  // for min
 #include <array>      // for array
-#include <chrono>  // for operator-, milliseconds, duration, operator>=, time_point, common_type<>::type
+#include <chrono>  // for operator-, milliseconds, duration, operator<=>, time_point, common_type<>::type
+#include <compare>  // for operator>=, strong_ordering
 #include <csignal>  // for signal, raise, SIGTSTP, SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM, SIGWINCH
 #include <cstdio>   // for fileno, size_t, stdin
 #include <ftxui/component/task.hpp>  // for Task, Closure, AnimationTask
@@ -136,14 +137,14 @@ void EventListener(std::atomic<bool>* quit, Sender<Task> out) {
 }
 
 extern "C" {
-  EMSCRIPTEN_KEEPALIVE
-  void ftxui_on_resize(int columns, int rows) {
-    Terminal::SetFallbackSize({
-        columns,
-        rows,
-    });
-    std::raise(SIGWINCH);
-  }
+EMSCRIPTEN_KEEPALIVE
+void ftxui_on_resize(int columns, int rows) {
+  Terminal::SetFallbackSize({
+      columns,
+      rows,
+  });
+  std::raise(SIGWINCH);
+}
 }
 
 #else
diff --git a/src/ftxui/component/slider.cpp b/src/ftxui/component/slider.cpp
index de07e2c2e5b5ef56d2bbf51016fd43de49de7e32..5312751d43437f48ad347326a233f4a358c918f3 100644
--- a/src/ftxui/component/slider.cpp
+++ b/src/ftxui/component/slider.cpp
@@ -1,46 +1,108 @@
-#include <string>   // for allocator
-#include <utility>  // for move
+#include <algorithm>                              // for max, min
+#include <ftxui/component/component_options.hpp>  // for SliderOption
+#include <string>                                 // for allocator
 
 #include "ftxui/component/captured_mouse.hpp"  // for CapturedMouse
 #include "ftxui/component/component.hpp"       // for Make, Slider
 #include "ftxui/component/component_base.hpp"  // for ComponentBase
-#include "ftxui/component/event.hpp"  // for Event, Event::ArrowLeft, Event::ArrowRight
+#include "ftxui/component/event.hpp"  // for Event, Event::ArrowDown, Event::ArrowLeft, Event::ArrowRight, Event::ArrowUp
 #include "ftxui/component/mouse.hpp"  // for Mouse, Mouse::Left, Mouse::Pressed, Mouse::Released
 #include "ftxui/component/screen_interactive.hpp"  // for Component
-#include "ftxui/dom/elements.hpp"  // for operator|, text, Element, reflect, xflex, gauge, hbox, underlined, color, dim, vcenter
+#include "ftxui/dom/elements.hpp"  // for operator|, text, GaugeDirection, Element, xflex, hbox, color, underlined, GaugeDirection::Down, GaugeDirection::Left, GaugeDirection::Right, GaugeDirection::Up, reflect, Decorator, dim, vcenter, yflex, gaugeDirection
 #include "ftxui/screen/box.hpp"    // for Box
-#include "ftxui/screen/color.hpp"  // for Color, Color::GrayDark, Color::GrayLight
-#include "ftxui/util/ref.hpp"      // for StringRef
+#include "ftxui/screen/color.hpp"  // for Color, Color::GrayDark, Color::White
+#include "ftxui/screen/util.hpp"   // for clamp
+#include "ftxui/util/ref.hpp"      // for ConstRef, ConstStringRef, Ref
 
 namespace ftxui {
 
+namespace {
+Decorator flexDirection(GaugeDirection direction) {
+  switch (direction) {
+    case GaugeDirection::Up:
+    case GaugeDirection::Down:
+      return yflex;
+    case GaugeDirection::Left:
+    case GaugeDirection::Right:
+      return xflex;
+  }
+  return xflex;  // NOT_REACHED()
+}
+}  // namespace
+
 template <class T>
 class SliderBase : public ComponentBase {
  public:
-  SliderBase(ConstStringRef label,
-             Ref<T> value,
-             ConstRef<T> min,
-             ConstRef<T> max,
-             ConstRef<T> increment)
-      : label_(std::move(label)),
-        value_(value),
-        min_(min),
-        max_(max),
-        increment_(increment) {}
+  SliderBase(Ref<SliderOption<T>> options)
+      : value_(options->value),
+        min_(options->min),
+        max_(options->max),
+        increment_(options->increment),
+        options_(options) {}
 
   Element Render() override {
-    auto gauge_color =
-        Focused() ? color(Color::GrayLight) : color(Color::GrayDark);
+    auto gauge_color = Focused() ? color(options_->color_active)
+                                 : color(options_->color_inactive);
     float percent = float(value_() - min_()) / float(max_() - min_());
-    return hbox({
-               text(label_()) | dim | vcenter,
-               hbox({
-                   text("["),
-                   gauge(percent) | underlined | xflex | reflect(gauge_box_),
-                   text("]"),
-               }) | xflex,
-           }) |
-           gauge_color | xflex | reflect(box_);
+    return gaugeDirection(percent, options_->direction) |
+           flexDirection(options_->direction) | reflect(gauge_box_) |
+           gauge_color;
+  }
+
+  void OnLeft() {
+    switch (options_->direction) {
+      case GaugeDirection::Right:
+        value_() -= increment_();
+        break;
+      case GaugeDirection::Left:
+        value_() += increment_();
+        break;
+      case GaugeDirection::Up:
+      case GaugeDirection::Down:
+        break;
+    }
+  }
+
+  void OnRight() {
+    switch (options_->direction) {
+      case GaugeDirection::Right:
+        value_() += increment_();
+        break;
+      case GaugeDirection::Left:
+        value_() -= increment_();
+        break;
+      case GaugeDirection::Up:
+      case GaugeDirection::Down:
+        break;
+    }
+  }
+
+  void OnUp() {
+    switch (options_->direction) {
+      case GaugeDirection::Up:
+        value_() -= increment_();
+        break;
+      case GaugeDirection::Down:
+        value_() += increment_();
+        break;
+      case GaugeDirection::Left:
+      case GaugeDirection::Right:
+        break;
+    }
+  }
+
+  void OnDown() {
+    switch (options_->direction) {
+      case GaugeDirection::Down:
+        value_() -= increment_();
+        break;
+      case GaugeDirection::Up:
+        value_() += increment_();
+        break;
+      case GaugeDirection::Left:
+      case GaugeDirection::Right:
+        break;
+    }
   }
 
   bool OnEvent(Event event) final {
@@ -48,17 +110,23 @@ class SliderBase : public ComponentBase {
       return OnMouseEvent(event);
     }
 
+    T old_value = value_();
     if (event == Event::ArrowLeft || event == Event::Character('h')) {
-      value_() -= increment_();
-      value_() = std::max(value_(), min_());
-      return true;
+      OnLeft();
     }
-
     if (event == Event::ArrowRight || event == Event::Character('l')) {
-      value_() += increment_();
-      value_() = std::min(*value_, max_());
-      return true;
+      OnRight();
+    }
+    if (event == Event::ArrowUp || event == Event::Character('k')) {
+      OnDown();
     }
+    if (event == Event::ArrowDown || event == Event::Character('j')) {
+      OnUp();
+    }
+
+    value_() = util::clamp(value_(), min_(), max_());
+    if (old_value != value_())
+      return true;
 
     return ComponentBase::OnEvent(event);
   }
@@ -69,7 +137,8 @@ class SliderBase : public ComponentBase {
       return true;
     }
 
-    if (box_.Contain(event.mouse().x, event.mouse().y) && CaptureMouse(event)) {
+    if (gauge_box_.Contain(event.mouse().x, event.mouse().y) &&
+        CaptureMouse(event)) {
       TakeFocus();
     }
 
@@ -81,9 +150,32 @@ class SliderBase : public ComponentBase {
     }
 
     if (captured_mouse_) {
-      value_() = min_() + (event.mouse().x - gauge_box_.x_min) *
-                              (max_() - min_()) /
-                              (gauge_box_.x_max - gauge_box_.x_min);
+      switch (options_->direction) {
+        case GaugeDirection::Right: {
+          value_() = min_() + (event.mouse().x - gauge_box_.x_min) *
+                                  (max_() - min_()) /
+                                  (gauge_box_.x_max - gauge_box_.x_min);
+          break;
+        }
+        case GaugeDirection::Left: {
+          value_() = max_() - (event.mouse().x - gauge_box_.x_min) *
+                                  (max_() - min_()) /
+                                  (gauge_box_.x_max - gauge_box_.x_min);
+          break;
+        }
+        case GaugeDirection::Down: {
+          value_() = min_() + (event.mouse().y - gauge_box_.y_min) *
+                                  (max_() - min_()) /
+                                  (gauge_box_.y_max - gauge_box_.y_min);
+          break;
+        }
+        case GaugeDirection::Up: {
+          value_() = max_() - (event.mouse().y - gauge_box_.y_min) *
+                                  (max_() - min_()) /
+                                  (gauge_box_.y_max - gauge_box_.y_min);
+          break;
+        }
+      }
       value_() = std::max(min_(), std::min(max_(), value_()));
       return true;
     }
@@ -93,16 +185,60 @@ class SliderBase : public ComponentBase {
   bool Focusable() const final { return true; }
 
  private:
-  ConstStringRef label_;
   Ref<T> value_;
   ConstRef<T> min_;
   ConstRef<T> max_;
   ConstRef<T> increment_;
-  Box box_;
+  Ref<SliderOption<T>> options_;
   Box gauge_box_;
   CapturedMouse captured_mouse_;
 };
 
+class SliderWithLabel : public ComponentBase {
+ public:
+  SliderWithLabel(ConstStringRef label, Component inner) : label_(label) {
+    Add(inner);
+    SetActiveChild(inner);
+  }
+
+ private:
+  bool OnEvent(Event event) final {
+    if (ComponentBase::OnEvent(event))
+      return true;
+
+    if (!event.is_mouse()) {
+      return false;
+    }
+
+    if (!box_.Contain(event.mouse().x, event.mouse().y)) {
+      return false;
+    }
+
+    if (!CaptureMouse(event)) {
+      return false;
+    }
+
+    TakeFocus();
+    return true;
+  }
+
+  Element Render() override {
+    auto gauge_color = Focused() ? color(Color::White) : color(Color::GrayDark);
+    return hbox({
+               text(label_()) | dim | vcenter,
+               hbox({
+                   text("["),
+                   ComponentBase::Render() | underlined,
+                   text("]"),
+               }) | xflex,
+           }) |
+           gauge_color | xflex | reflect(box_);
+  }
+
+  ConstStringRef label_;
+  Box box_;
+};
+
 /// @brief An horizontal slider.
 /// @param label The name of the slider.
 /// @param value The current value of the slider.
@@ -130,22 +266,64 @@ Component Slider(ConstStringRef label,
                  ConstRef<int> min,
                  ConstRef<int> max,
                  ConstRef<int> increment) {
-  return Make<SliderBase<int>>(std::move(label), value, min, max, increment);
+  auto slider = Make<SliderBase<int>>(SliderOption<int>({
+      .value = value,
+      .min = min,
+      .max = max,
+      .increment = increment,
+  }));
+  return Make<SliderWithLabel>(label, slider);
 }
+
 Component Slider(ConstStringRef label,
                  Ref<float> value,
                  ConstRef<float> min,
                  ConstRef<float> max,
                  ConstRef<float> increment) {
-  return Make<SliderBase<float>>(std::move(label), value, min, max, increment);
+  auto slider = Make<SliderBase<float>>(SliderOption<float>({
+      .value = value,
+      .min = min,
+      .max = max,
+      .increment = increment,
+  }));
+  return Make<SliderWithLabel>(label, slider);
 }
 Component Slider(ConstStringRef label,
                  Ref<long> value,
                  ConstRef<long> min,
                  ConstRef<long> max,
                  ConstRef<long> increment) {
-  return Make<SliderBase<long>>(std::move(label), value, min, max, increment);
+  auto slider = Make<SliderBase<long>>(SliderOption<long>({
+      .value = value,
+      .min = min,
+      .max = max,
+      .increment = increment,
+  }));
+  return Make<SliderWithLabel>(label, slider);
+}
+
+/// @brief A slider in any direction.
+/// @param option The options
+/// ### Example
+///
+/// ```cpp
+/// auto screen = ScreenInteractive::TerminalOutput();
+/// int value = 50;
+/// auto slider = Slider({
+///   .value = &value,
+///   .min = 0,
+///   .max = 100,
+///   .increment= 20,
+/// });
+/// screen.Loop(slider);
+/// ```
+template <typename T>
+Component Slider(SliderOption<T> options) {
+  return Make<SliderBase<T>>(options);
 }
+template Component Slider(SliderOption<int> options);
+template Component Slider(SliderOption<float> options);
+template Component Slider(SliderOption<long> options);
 
 }  // namespace ftxui
 
diff --git a/src/ftxui/component/slider_test.cpp b/src/ftxui/component/slider_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ecaf3ed1e86317a6078ff4f7a344346882ff65f4
--- /dev/null
+++ b/src/ftxui/component/slider_test.cpp
@@ -0,0 +1,136 @@
+#include <gtest/gtest.h>  // for AssertionResult, Message, TestPartResult, Test, EXPECT_TRUE, EXPECT_EQ, SuiteApiResolver, TestInfo (ptr only), EXPECT_FALSE, TEST, TestFactoryImpl
+#include <ftxui/component/mouse.hpp>  // for Mouse, Mouse::Left, Mouse::Pressed, Mouse::Released
+#include <ftxui/dom/elements.hpp>  // for GaugeDirection, GaugeDirection::Down, GaugeDirection::Left, GaugeDirection::Right, GaugeDirection::Up
+#include <memory>  // for __shared_ptr_access, shared_ptr, allocator
+
+#include "ftxui/component/component.hpp"       // for Slider
+#include "ftxui/component/component_base.hpp"  // for ComponentBase
+#include "ftxui/component/event.hpp"           // for Event
+#include "ftxui/dom/node.hpp"                  // for Render
+#include "ftxui/screen/screen.hpp"             // for Screen
+
+namespace ftxui {
+
+namespace {
+Event MousePressed(int x, int y) {
+  Mouse mouse;
+  mouse.button = Mouse::Left;
+  mouse.motion = Mouse::Pressed;
+  mouse.shift = false;
+  mouse.meta = false;
+  mouse.control = false;
+  mouse.x = x;
+  mouse.y = y;
+  return Event::Mouse("jjj", mouse);
+}
+
+Event MouseReleased(int x, int y) {
+  Mouse mouse;
+  mouse.button = Mouse::Left;
+  mouse.motion = Mouse::Released;
+  mouse.shift = false;
+  mouse.meta = false;
+  mouse.control = false;
+  mouse.x = x;
+  mouse.y = y;
+  return Event::Mouse("jjj", mouse);
+}
+}  // namespace
+
+TEST(SliderTest, Right) {
+  int value = 50;
+  auto slider = Slider<int>({
+      .value = &value,
+      .min = 0,
+      .max = 100,
+      .increment = 10,
+      .direction = GaugeDirection::Right,
+  });
+  Screen screen(11, 1);
+  Render(screen, slider->Render());
+  EXPECT_TRUE(slider->OnEvent(MousePressed(3, 0)));
+  EXPECT_EQ(value, 30);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(9, 0)));
+  EXPECT_EQ(value, 90);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(9, 2)));
+  EXPECT_EQ(value, 90);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(5, 2)));
+  EXPECT_EQ(value, 50);
+  EXPECT_TRUE(slider->OnEvent(MouseReleased(5, 2)));
+  EXPECT_FALSE(slider->OnEvent(MousePressed(5, 2)));
+}
+
+TEST(SliderTest, Left) {
+  int value = 50;
+  auto slider = Slider<int>({
+      .value = &value,
+      .min = 0,
+      .max = 100,
+      .increment = 10,
+      .direction = GaugeDirection::Left,
+  });
+  Screen screen(11, 1);
+  Render(screen, slider->Render());
+  EXPECT_TRUE(slider->OnEvent(MousePressed(3, 0)));
+  EXPECT_EQ(value, 70);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(9, 0)));
+  EXPECT_EQ(value, 10);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(9, 2)));
+  EXPECT_EQ(value, 10);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(5, 2)));
+  EXPECT_EQ(value, 50);
+  EXPECT_TRUE(slider->OnEvent(MouseReleased(5, 2)));
+  EXPECT_FALSE(slider->OnEvent(MousePressed(5, 2)));
+}
+
+TEST(SliderTest, Down) {
+  int value = 50;
+  auto slider = Slider<int>({
+      .value = &value,
+      .min = 0,
+      .max = 100,
+      .increment = 10,
+      .direction = GaugeDirection::Down,
+  });
+  Screen screen(1, 11);
+  Render(screen, slider->Render());
+  EXPECT_TRUE(slider->OnEvent(MousePressed(0, 3)));
+  EXPECT_EQ(value, 30);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(0, 9)));
+  EXPECT_EQ(value, 90);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(2, 9)));
+  EXPECT_EQ(value, 90);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(2, 5)));
+  EXPECT_EQ(value, 50);
+  EXPECT_TRUE(slider->OnEvent(MouseReleased(2, 5)));
+  EXPECT_FALSE(slider->OnEvent(MousePressed(2, 5)));
+}
+
+TEST(SliderTest, Up) {
+  int value = 50;
+  auto slider = Slider<int>({
+      .value = &value,
+      .min = 0,
+      .max = 100,
+      .increment = 10,
+      .direction = GaugeDirection::Up,
+  });
+  Screen screen(1, 11);
+  Render(screen, slider->Render());
+  EXPECT_TRUE(slider->OnEvent(MousePressed(0, 3)));
+  EXPECT_EQ(value, 70);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(0, 9)));
+  EXPECT_EQ(value, 10);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(2, 9)));
+  EXPECT_EQ(value, 10);
+  EXPECT_TRUE(slider->OnEvent(MousePressed(2, 5)));
+  EXPECT_EQ(value, 50);
+  EXPECT_TRUE(slider->OnEvent(MouseReleased(2, 5)));
+  EXPECT_FALSE(slider->OnEvent(MousePressed(2, 5)));
+}
+
+}  // namespace ftxui
+
+// Copyright 2022 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/screen/screen.cpp b/src/ftxui/screen/screen.cpp
index dc30d51f228014a0c8a66f3cabe3fb6170f17a46..ed738317af6ece6a83b834a23867cc42f897574a 100644
--- a/src/ftxui/screen/screen.cpp
+++ b/src/ftxui/screen/screen.cpp
@@ -55,7 +55,7 @@ void UpdatePixelStyle(std::stringstream& ss,
   if (next == previous) {
     return;
   }
-  
+
   if ((!next.bold && previous.bold) ||  //
       (!next.dim && previous.dim)) {
     ss << "\x1B[22m";  // BOLD_RESET and DIM_RESET