diff --git a/CHANGELOG.md b/CHANGELOG.md
index 847e6bca53d1c313ace064ce6c951ef88a10cef5..d3cefa5aa0dcecb15beb8f114c0da0193b508b83 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,26 @@ current (development)
 ### Component
 - Feature: Add support for `Input`'s insert mode. Add `InputOption::insert`
   option. Added by @mingsheng13.
+- Feature/Bugfix/Breaking change: `Mouse transition`:
+  This fixes: https://github.com/ArthurSonzogni/FTXUI/issues/773
+  Dragging the mouse with the left button pressed now avoids activating multiple
+  checkboxes.
+
+  Add support for detecting mouse press transition. Added:
+  ```cpp
+  // The previous mouse event.
+  Mouse Mouse::previous;
+
+  // Return whether the mouse transitionned from:
+  // released to pressed => IsPressed()
+  // pressed to pressed => IsHeld()
+  // pressed to released => IsReleased()
+  bool Mouse::IsPressed(Button button) const;
+  bool Mouse::IsHeld(Button button) const;
+  bool Mouse::IsReleased(Button button) const;
+  ```
+  A couple of components are now activated when the mouse is pressed,
+  as opposed to released.
 - Bugfix: `Input` `onchange` was not called on backspace or delete key.
   Fixed by @chrysante in chrysante in PR #776.
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 583ed46a2723070e9ce959e152c6322a3c81d6e4..6dc246bf144530aeca432fd9e5f00416966c573f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -123,6 +123,7 @@ add_library(component
   src/ftxui/component/maybe.cpp
   src/ftxui/component/menu.cpp
   src/ftxui/component/modal.cpp
+  src/ftxui/component/mouse.cpp
   src/ftxui/component/radiobox.cpp
   src/ftxui/component/radiobox.cpp
   src/ftxui/component/renderer.cpp
diff --git a/include/ftxui/component/mouse.hpp b/include/ftxui/component/mouse.hpp
index 3c61008dc3f3044ced0664bbe8ec69e7f5507137..38bf1e1516a5f1332a8e1280264cb9cb911607ee 100644
--- a/include/ftxui/component/mouse.hpp
+++ b/include/ftxui/component/mouse.hpp
@@ -23,6 +23,11 @@ struct Mouse {
     Pressed = 1,
   };
 
+  // Utility function to check the variations of the mouse state.
+  bool IsPressed(Button btn = Left) const;   // Released => Pressed.
+  bool IsHeld(Button btn = Left) const;      // Pressed => Pressed.
+  bool IsReleased(Button btn = Left) const;  // Pressed => Released.
+
   // Button
   Button button = Button::None;
 
@@ -37,6 +42,9 @@ struct Mouse {
   // Coordinates:
   int x = 0;
   int y = 0;
+
+  // Previous mouse event, if any.
+  Mouse* previous = nullptr;
 };
 
 }  // namespace ftxui
diff --git a/include/ftxui/component/screen_interactive.hpp b/include/ftxui/component/screen_interactive.hpp
index 10d022c670d08bf48f73f192250d7a3f5df9ea7c..fd3a629f180da97a3db9f6ab59754ceabe51caa9 100644
--- a/include/ftxui/component/screen_interactive.hpp
+++ b/include/ftxui/component/screen_interactive.hpp
@@ -112,6 +112,7 @@ class ScreenInteractive : public Screen {
 
   bool frame_valid_ = false;
 
+  Mouse latest_mouse_event_;
   friend class Loop;
 
  public:
diff --git a/src/ftxui/component/button.cpp b/src/ftxui/component/button.cpp
index c983f31f2acbe79fd5c13b096c36b8aea2ef9f37..229c32ee3b51f1192bac48cde65e9ba85a283487 100644
--- a/src/ftxui/component/button.cpp
+++ b/src/ftxui/component/button.cpp
@@ -124,8 +124,7 @@ class ButtonBase : public ComponentBase, public ButtonOption {
       return false;
     }
 
-    if (event.mouse().button == Mouse::Left &&
-        event.mouse().motion == Mouse::Pressed) {
+    if (event.mouse().IsPressed()) {
       TakeFocus();
       OnClick();
       return true;
diff --git a/src/ftxui/component/checkbox.cpp b/src/ftxui/component/checkbox.cpp
index ebfa46d8b298a44c0e242998178cc9109683645c..bf1324f07119d20d89a18e430037f60884cf77ee 100644
--- a/src/ftxui/component/checkbox.cpp
+++ b/src/ftxui/component/checkbox.cpp
@@ -69,8 +69,7 @@ class CheckboxBase : public ComponentBase, public CheckboxOption {
       return false;
     }
 
-    if (event.mouse().button == Mouse::Left &&
-        event.mouse().motion == Mouse::Pressed) {
+    if (event.mouse().IsPressed()) {
       *checked = !*checked;
       on_change();
       return true;
diff --git a/src/ftxui/component/input.cpp b/src/ftxui/component/input.cpp
index 7228f1310c5a038ea600a3443201e7483c4f9d4e..b41a9b4ac12b37582e02a5e077bf1b32ec108998 100644
--- a/src/ftxui/component/input.cpp
+++ b/src/ftxui/component/input.cpp
@@ -466,8 +466,7 @@ class InputBase : public ComponentBase, public InputOption {
       return false;
     }
 
-    if (event.mouse().button != Mouse::Left ||
-        event.mouse().motion != Mouse::Pressed) {
+    if (!event.mouse().IsPressed()) {
       return false;
     }
 
diff --git a/src/ftxui/component/menu.cpp b/src/ftxui/component/menu.cpp
index 7f6b92d1d1a6c656e2b293d5040e4891db8a6ca6..890e500f2900637ca29ccaad395c1a018ce38e75 100644
--- a/src/ftxui/component/menu.cpp
+++ b/src/ftxui/component/menu.cpp
@@ -318,8 +318,7 @@ class MenuBase : public ComponentBase, public MenuOption {
 
       TakeFocus();
       focused_entry() = i;
-      if (event.mouse().button == Mouse::Left &&
-          event.mouse().motion == Mouse::Released) {
+      if (event.mouse().IsPressed()) {
         if (selected() != i) {
           selected() = i;
           selected_previous_ = selected();
@@ -683,8 +682,7 @@ Component MenuEntry(MenuEntryOption option) {
         return false;
       }
 
-      if (event.mouse().button == Mouse::Left &&
-          event.mouse().motion == Mouse::Released) {
+      if (event.mouse().IsPressed()) {
         TakeFocus();
         return true;
       }
diff --git a/src/ftxui/component/mouse.cpp b/src/ftxui/component/mouse.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..74e51d2e436625b556bc77f4ecb0cd52951361d8
--- /dev/null
+++ b/src/ftxui/component/mouse.cpp
@@ -0,0 +1,36 @@
+// Copyright 2023 Arthur Sonzogni. All rights reserved.
+// Use of this source code is governed by the MIT license that can be found in
+// the LICENSE file.
+
+#include "ftxui/component/mouse.hpp"
+
+namespace ftxui {
+
+namespace {
+bool IsDown(const Mouse* mouse, Mouse::Button btn) {
+  return mouse->button == btn && mouse->motion == Mouse::Pressed;
+}
+}  // namespace
+
+/// Return whether the mouse transitionned from released to pressed.
+/// This is useful to detect a click.
+/// @arg btn The button to check.
+bool Mouse::IsPressed(Button btn) const {
+  return IsDown(this, btn) && (!previous || !IsDown(previous, btn));
+}
+
+/// Return whether the mouse is currently held.
+/// This is useful to detect a drag.
+/// @arg btn The button to check.
+bool Mouse::IsHeld(Button btn) const {
+  return IsDown(this, btn) && previous && IsDown(previous, btn);
+}
+
+/// Return whether the mouse transitionned from pressed to released.
+/// This is useful to detect a click.
+/// @arg btn The button to check.
+bool Mouse::IsReleased(Button btn) const {
+  return !IsDown(this, btn) && (previous && IsDown(previous, btn));
+}
+
+}  // namespace ftxui
diff --git a/src/ftxui/component/radiobox.cpp b/src/ftxui/component/radiobox.cpp
index 004a2428983f102a0ed3dc17463ade0bcdca64b1..0d00f403d3b0017fc427395dfed432329017b472 100644
--- a/src/ftxui/component/radiobox.cpp
+++ b/src/ftxui/component/radiobox.cpp
@@ -123,8 +123,7 @@ class RadioboxBase : public ComponentBase, public RadioboxOption {
 
       TakeFocus();
       focused_entry() = i;
-      if (event.mouse().button == Mouse::Left &&
-          event.mouse().motion == Mouse::Released) {
+      if (event.mouse().IsPressed()) {
         if (selected() != i) {
           selected() = i;
           on_change();
diff --git a/src/ftxui/component/resizable_split.cpp b/src/ftxui/component/resizable_split.cpp
index 9e0d62e35d1f797341c65dc7d925dcb76f032d50..614fd41714bf9a1e65ee221c1ea9a6f51cfbc192 100644
--- a/src/ftxui/component/resizable_split.cpp
+++ b/src/ftxui/component/resizable_split.cpp
@@ -42,8 +42,7 @@ class ResizableSplitBase : public ComponentBase {
       return true;
     }
 
-    if (event.mouse().button == Mouse::Left &&
-        event.mouse().motion == Mouse::Pressed &&
+    if (event.mouse().IsPressed() &&
         separator_box_.Contain(event.mouse().x, event.mouse().y) &&
         !captured_mouse_) {
       captured_mouse_ = CaptureMouse(event);
diff --git a/src/ftxui/component/screen_interactive.cpp b/src/ftxui/component/screen_interactive.cpp
index ca908609be0d61781f0c2f2c54390837ba4aa379..33660514a1bd98780ca9863e7b9ed45ed7e0f460 100644
--- a/src/ftxui/component/screen_interactive.cpp
+++ b/src/ftxui/component/screen_interactive.cpp
@@ -689,11 +689,17 @@ void ScreenInteractive::HandleTask(Component component, Task& task) {
       if (arg.is_mouse()) {
         arg.mouse().x -= cursor_x_;
         arg.mouse().y -= cursor_y_;
+        arg.mouse().previous = &latest_mouse_event_;
       }
 
       arg.screen_ = this;
       component->OnEvent(arg);
       frame_valid_ = false;
+
+      if (arg.is_mouse()) {
+        latest_mouse_event_ = arg.mouse();
+        latest_mouse_event_.previous = nullptr;
+      }
       return;
     }
 
diff --git a/src/ftxui/component/slider.cpp b/src/ftxui/component/slider.cpp
index d30b87b79005ff188cd29aecbbe2f1d4b1159ddd..80d29fdb8c3caf608f01c61f1d6b09f79602dd97 100644
--- a/src/ftxui/component/slider.cpp
+++ b/src/ftxui/component/slider.cpp
@@ -174,8 +174,7 @@ class SliderBase : public ComponentBase {
       return true;
     }
 
-    if (event.mouse().button != Mouse::Left ||
-        event.mouse().motion != Mouse::Pressed) {
+    if (!event.mouse().IsPressed()) {
       return false;
     }
 
diff --git a/src/ftxui/component/window.cpp b/src/ftxui/component/window.cpp
index daed7e10eee04d0e82874f07b08e0ba697ccf143..cae72b45637afccda0338a2af38639a00aa8808a 100644
--- a/src/ftxui/component/window.cpp
+++ b/src/ftxui/component/window.cpp
@@ -225,8 +225,7 @@ class WindowImpl : public ComponentBase, public WindowOptions {
       return true;
     }
 
-    if (event.mouse().button != Mouse::Left ||
-        event.mouse().motion != Mouse::Pressed) {
+    if (!event.mouse().IsPressed()) {
       return true;
     }