update data bind mode to flags

change how we store data bind mode.
This will be helpful once we implement converters to identify whether a converter's main direction is "toSource" or "toTarget".
It also cleans up how the modal works and saves changes in real time instead of doing it on "Save"

<img width="606" alt="data_bind_mode" src="https://github.com/user-attachments/assets/3662df84-e05a-4ea0-aaea-37e0b1294da0">

Diffs=
49cabe3cb update data bind mode to flags (#7612)

Co-authored-by: hernan <hernan@rive.app>
diff --git a/.rive_head b/.rive_head
index fb5018f..5cb2d55 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-6c5c79b751c50fa4393fb0e44624635861bc3f3b
+49cabe3cbd9c9683bd704e0d72a455d698bfe061
diff --git a/dev/defs/data_bind/data_bind.json b/dev/defs/data_bind/data_bind.json
index eaf9be2..c93b559 100644
--- a/dev/defs/data_bind/data_bind.json
+++ b/dev/defs/data_bind/data_bind.json
@@ -26,15 +26,13 @@
       },
       "description": "The property that is targeted."
     },
-    "modeValue": {
+    "flags": {
       "type": "uint",
-      "typeRuntime": "uint",
       "initialValue": "0",
       "key": {
         "int": 587,
-        "string": "modevalue"
-      },
-      "description": "Backing enum value for the binding mode."
+        "string": "flags"
+      }
     }
   }
 }
\ No newline at end of file
diff --git a/include/rive/data_bind/data_bind_context.hpp b/include/rive/data_bind/data_bind_context.hpp
index 113b7fb..a6bdd46 100644
--- a/include/rive/data_bind/data_bind_context.hpp
+++ b/include/rive/data_bind/data_bind_context.hpp
@@ -13,11 +13,9 @@
     std::vector<uint32_t> m_SourcePathIdsBuffer;
 
 public:
-    void update(ComponentDirt value) override;
     void decodeSourcePathIds(Span<const uint8_t> value) override;
     void copySourcePathIds(const DataBindContextBase& object) override;
     void bind() override;
-    void updateSourceBinding() override;
     ViewModelInstanceValue* source() { return m_Source; };
 };
 } // namespace rive
diff --git a/include/rive/data_bind/data_bind_mode.hpp b/include/rive/data_bind/data_bind_mode.hpp
deleted file mode 100644
index 692e62d..0000000
--- a/include/rive/data_bind/data_bind_mode.hpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _RIVE_DATA_BIND_MODE_HPP_
-#define _RIVE_DATA_BIND_MODE_HPP_
-namespace rive
-{
-enum class DataBindMode : unsigned int
-{
-    oneWay = 0,
-    twoWay = 1,
-    oneWayToSource = 2,
-    once = 3,
-};
-}
-#endif
\ No newline at end of file
diff --git a/include/rive/data_bind_flags.hpp b/include/rive/data_bind_flags.hpp
new file mode 100644
index 0000000..2d8561f
--- /dev/null
+++ b/include/rive/data_bind_flags.hpp
@@ -0,0 +1,29 @@
+#ifndef _RIVE_DATA_BIND_FLAGS_HPP_
+#define _RIVE_DATA_BIND_FLAGS_HPP_
+
+#include "rive/enum_bitset.hpp"
+
+namespace rive
+{
+enum class DataBindFlags : unsigned short
+{
+    /// Whether the main binding direction is to source (0) or to target (1)
+    Direction = 1 << 0,
+
+    /// Whether the binding direction is twoWay
+    TwoWay = 1 << 1,
+
+    /// Whether the binding happens only once
+    Once = 1 << 2,
+
+    /// Flag if set to target
+    ToTarget = 0,
+
+    /// Flag if set to source
+    ToSource = 1 << 0,
+
+};
+
+RIVE_MAKE_ENUM_BITSET(DataBindFlags)
+} // namespace rive
+#endif
diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp
index 519c064..eb3a240 100644
--- a/include/rive/generated/core_registry.hpp
+++ b/include/rive/generated/core_registry.hpp
@@ -926,8 +926,8 @@
             case DataBindBase::propertyKeyPropertyKey:
                 object->as<DataBindBase>()->propertyKey(value);
                 break;
-            case DataBindBase::modeValuePropertyKey:
-                object->as<DataBindBase>()->modeValue(value);
+            case DataBindBase::flagsPropertyKey:
+                object->as<DataBindBase>()->flags(value);
                 break;
             case WeightBase::valuesPropertyKey:
                 object->as<WeightBase>()->values(value);
@@ -1884,8 +1884,8 @@
                 return object->as<DataBindBase>()->targetId();
             case DataBindBase::propertyKeyPropertyKey:
                 return object->as<DataBindBase>()->propertyKey();
-            case DataBindBase::modeValuePropertyKey:
-                return object->as<DataBindBase>()->modeValue();
+            case DataBindBase::flagsPropertyKey:
+                return object->as<DataBindBase>()->flags();
             case WeightBase::valuesPropertyKey:
                 return object->as<WeightBase>()->values();
             case WeightBase::indicesPropertyKey:
@@ -2472,7 +2472,7 @@
             case OpenUrlEventBase::targetValuePropertyKey:
             case DataBindBase::targetIdPropertyKey:
             case DataBindBase::propertyKeyPropertyKey:
-            case DataBindBase::modeValuePropertyKey:
+            case DataBindBase::flagsPropertyKey:
             case WeightBase::valuesPropertyKey:
             case WeightBase::indicesPropertyKey:
             case TendonBase::boneIdPropertyKey:
@@ -3010,7 +3010,7 @@
                 return object->is<DataBindBase>();
             case DataBindBase::propertyKeyPropertyKey:
                 return object->is<DataBindBase>();
-            case DataBindBase::modeValuePropertyKey:
+            case DataBindBase::flagsPropertyKey:
                 return object->is<DataBindBase>();
             case WeightBase::valuesPropertyKey:
                 return object->is<WeightBase>();
diff --git a/include/rive/generated/data_bind/data_bind_base.hpp b/include/rive/generated/data_bind/data_bind_base.hpp
index ed0d48d..4c73ffc 100644
--- a/include/rive/generated/data_bind/data_bind_base.hpp
+++ b/include/rive/generated/data_bind/data_bind_base.hpp
@@ -30,12 +30,12 @@
 
     static const uint16_t targetIdPropertyKey = 585;
     static const uint16_t propertyKeyPropertyKey = 586;
-    static const uint16_t modeValuePropertyKey = 587;
+    static const uint16_t flagsPropertyKey = 587;
 
 private:
     uint32_t m_TargetId = -1;
     uint32_t m_PropertyKey = Core::invalidPropertyKey;
-    uint32_t m_ModeValue = 0;
+    uint32_t m_Flags = 0;
 
 public:
     inline uint32_t targetId() const { return m_TargetId; }
@@ -60,15 +60,15 @@
         propertyKeyChanged();
     }
 
-    inline uint32_t modeValue() const { return m_ModeValue; }
-    void modeValue(uint32_t value)
+    inline uint32_t flags() const { return m_Flags; }
+    void flags(uint32_t value)
     {
-        if (m_ModeValue == value)
+        if (m_Flags == value)
         {
             return;
         }
-        m_ModeValue = value;
-        modeValueChanged();
+        m_Flags = value;
+        flagsChanged();
     }
 
     Core* clone() const override;
@@ -76,7 +76,7 @@
     {
         m_TargetId = object.m_TargetId;
         m_PropertyKey = object.m_PropertyKey;
-        m_ModeValue = object.m_ModeValue;
+        m_Flags = object.m_Flags;
         Component::copy(object);
     }
 
@@ -90,8 +90,8 @@
             case propertyKeyPropertyKey:
                 m_PropertyKey = CoreUintType::deserialize(reader);
                 return true;
-            case modeValuePropertyKey:
-                m_ModeValue = CoreUintType::deserialize(reader);
+            case flagsPropertyKey:
+                m_Flags = CoreUintType::deserialize(reader);
                 return true;
         }
         return Component::deserialize(propertyKey, reader);
@@ -100,7 +100,7 @@
 protected:
     virtual void targetIdChanged() {}
     virtual void propertyKeyChanged() {}
-    virtual void modeValueChanged() {}
+    virtual void flagsChanged() {}
 };
 } // namespace rive
 
diff --git a/src/artboard.cpp b/src/artboard.cpp
index a72cba2..47c5d04 100644
--- a/src/artboard.cpp
+++ b/src/artboard.cpp
@@ -4,7 +4,6 @@
 #include "rive/dependency_sorter.hpp"
 #include "rive/data_bind/data_bind.hpp"
 #include "rive/data_bind/data_bind_context.hpp"
-#include "rive/data_bind/data_bind_mode.hpp"
 #include "rive/draw_rules.hpp"
 #include "rive/draw_target.hpp"
 #include "rive/audio_event.hpp"
@@ -18,6 +17,7 @@
 #include "rive/importers/backboard_importer.hpp"
 #include "rive/nested_artboard.hpp"
 #include "rive/joystick.hpp"
+#include "rive/data_bind_flags.hpp"
 #include "rive/animation/nested_bool.hpp"
 #include "rive/animation/nested_number.hpp"
 #include "rive/animation/nested_trigger.hpp"
@@ -1050,16 +1050,19 @@
     for (auto component : *dataBinds)
     {
         auto dataBind = component->as<DataBind>();
-        auto mode = static_cast<DataBindMode>(dataBind->modeValue());
+        auto flags = static_cast<DataBindFlags>(dataBind->flags());
         // If the data bind reads from the target, we want to add it as dependent from any other
-        // data bind that writes into that target.
-        if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay)
+        // parent data bind that writes into that target.
+        if (((flags & DataBindFlags::Direction) == DataBindFlags::ToSource) ||
+            ((flags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay))
         {
             for (auto innerComponent : *dataBinds)
             {
                 auto dataBindParent = innerComponent->as<DataBind>();
-                auto parentMode = static_cast<DataBindMode>(dataBind->modeValue());
-                if (dataBindParent != dataBind && (parentMode != DataBindMode::oneWayToSource) &&
+                auto parentFlags = static_cast<DataBindFlags>(dataBindParent->flags());
+                if (dataBindParent != dataBind &&
+                    (((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToTarget) ||
+                     ((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay)) &&
                     dataBindParent->target() == dataBind->target() &&
                     dataBindParent->propertyKey() == dataBind->propertyKey())
                 {
@@ -1071,23 +1074,23 @@
         else
         {
             // If the data bind reads from a source we want to add it as dependent
-            // from any other data bind that writes into that source.
+            // from any other parent data bind that writes into that source.
             if (dataBind->is<DataBindContext>())
             {
                 for (auto innerComponent : *dataBinds)
                 {
-                    auto dataBindChild = innerComponent->as<DataBind>();
-                    if (dataBindChild != dataBind)
+                    auto dataBindParent = innerComponent->as<DataBind>();
+                    if (dataBindParent != dataBind)
                     {
-                        auto childMode = static_cast<DataBindMode>(dataBind->modeValue());
-                        if (childMode == DataBindMode::oneWayToSource ||
-                            childMode == DataBindMode::twoWay)
+                        auto parentFlags = static_cast<DataBindFlags>(dataBindParent->flags());
+                        if (((parentFlags & DataBindFlags::Direction) == DataBindFlags::ToSource) ||
+                            ((parentFlags & DataBindFlags::TwoWay) == DataBindFlags::TwoWay))
                         {
-                            if (dataBindChild->is<DataBindContext>() &&
-                                dataBindChild->as<DataBindContext>()->source() ==
+                            if (dataBindParent->is<DataBindContext>() &&
+                                dataBindParent->as<DataBindContext>()->source() ==
                                     dataBind->as<DataBindContext>()->source())
                             {
-                                dataBind->addDependent(dataBindChild);
+                                dataBindParent->addDependent(dataBind);
                                 break;
                             }
                         }
diff --git a/src/data_bind/data_bind.cpp b/src/data_bind/data_bind.cpp
index d6f3ce9..adfa276 100644
--- a/src/data_bind/data_bind.cpp
+++ b/src/data_bind/data_bind.cpp
@@ -1,6 +1,6 @@
 #include "rive/data_bind/data_bind.hpp"
-#include "rive/data_bind/data_bind_mode.hpp"
 #include "rive/artboard.hpp"
+#include "rive/data_bind_flags.hpp"
 #include "rive/generated/core_registry.hpp"
 #include "rive/data_bind/context/context_value.hpp"
 #include "rive/data_bind/context/context_value_boolean.hpp"
@@ -40,8 +40,9 @@
 void DataBind::buildDependencies()
 {
     Super::buildDependencies();
-    auto mode = static_cast<DataBindMode>(modeValue());
-    if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay)
+    auto flagsValue = static_cast<DataBindFlags>(flags());
+    if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource) ||
+        ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay))
     {
         m_target->addDependent(this);
     }
@@ -88,8 +89,9 @@
         {
             // TODO: @hernan review how dirt and mode work together. If dirt is not set for
             // certain modes, we might be able to skip the mode validation.
-            auto mode = static_cast<DataBindMode>(modeValue());
-            if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay)
+            auto flagsValue = static_cast<DataBindFlags>(flags());
+            if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToTarget) ||
+                ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay))
             {
                 m_ContextValue->apply(m_target, propertyKey());
             }
@@ -100,8 +102,9 @@
 
 void DataBind::updateSourceBinding()
 {
-    auto mode = static_cast<DataBindMode>(modeValue());
-    if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay)
+    auto flagsValue = static_cast<DataBindFlags>(flags());
+    if (((flagsValue & DataBindFlags::Direction) == DataBindFlags::ToSource) ||
+        ((flagsValue & DataBindFlags::TwoWay) == DataBindFlags::TwoWay))
     {
         if (m_ContextValue != nullptr)
         {
diff --git a/src/data_bind/data_bind_context.cpp b/src/data_bind/data_bind_context.cpp
index a249226..4bb86f6 100644
--- a/src/data_bind/data_bind_context.cpp
+++ b/src/data_bind/data_bind_context.cpp
@@ -1,5 +1,5 @@
+#include "rive/data_bind_flags.hpp"
 #include "rive/data_bind/data_bind_context.hpp"
-#include "rive/data_bind/data_bind_mode.hpp"
 #include "rive/data_bind/context/context_value_number.hpp"
 #include "rive/data_bind/context/context_value_string.hpp"
 #include "rive/data_bind/context/context_value_enum.hpp"
@@ -39,41 +39,4 @@
             Super::bind();
         }
     }
-}
-
-void DataBindContext::update(ComponentDirt value)
-{
-    if (m_Source != nullptr && m_ContextValue != nullptr)
-    {
-
-        // Use the ComponentDirt::Components flag to indicate the viewmodel has added or removed
-        // an element to a list.
-        if ((value & ComponentDirt::Components) == ComponentDirt::Components)
-        {
-            m_ContextValue->update(m_target);
-        }
-        if ((value & ComponentDirt::Bindings) == ComponentDirt::Bindings)
-        {
-            // TODO: @hernan review how dirt and mode work together. If dirt is not set for
-            // certain modes, we might be able to skip the mode validation.
-            auto mode = static_cast<DataBindMode>(modeValue());
-            if (mode == DataBindMode::oneWay || mode == DataBindMode::twoWay)
-            {
-                m_ContextValue->apply(m_target, propertyKey());
-            }
-        }
-    }
-    Super::update(value);
-}
-
-void DataBindContext::updateSourceBinding()
-{
-    auto mode = static_cast<DataBindMode>(modeValue());
-    if (mode == DataBindMode::oneWayToSource || mode == DataBindMode::twoWay)
-    {
-        if (m_ContextValue != nullptr)
-        {
-            m_ContextValue->applyToSource(m_target, propertyKey());
-        }
-    }
 }
\ No newline at end of file