void FlyoutShadowNode::updateProperties()

in vnext/Microsoft.ReactNative/Views/FlyoutViewManager.cpp [296:398]


void FlyoutShadowNode::updateProperties(winrt::Microsoft::ReactNative::JSValueObject &props) {
  m_updating = true;
  bool updateTargetElement = false;
  bool updateIsOpen = false;
  bool updateOffset = false;

  if (m_flyout == nullptr)
    return;

  for (auto &pair : props) {
    const std::string &propertyName = pair.first;
    const auto &propertyValue = pair.second;

    if (propertyName == "horizontalOffset") {
      if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Double ||
          propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Int64)
        m_horizontalOffset = propertyValue.AsSingle();
      else
        m_horizontalOffset = 0;

      updateOffset = true;
    } else if (propertyName == "isLightDismissEnabled") {
      if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean)
        m_isLightDismissEnabled = propertyValue.AsBoolean();
      else if (propertyValue.IsNull())
        m_isLightDismissEnabled = true;
      if (m_isOpen) {
        if (auto popup = GetFlyoutParentPopup()) {
          popup.IsLightDismissEnabled(m_isLightDismissEnabled);
        }
      }
    } else if (propertyName == "isOpen") {
      if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean) {
        bool isOpen = m_isOpen;
        m_isOpen = propertyValue.AsBoolean();
        if (isOpen != m_isOpen) {
          updateIsOpen = true;
        }
      }
    } else if (propertyName == "placement") {
      auto placement = json_type_traits<winrt::FlyoutPlacementMode>::parseJson(propertyValue);
      m_flyout.Placement(placement);
    } else if (propertyName == "target") {
      if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Double ||
          propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Int64) {
        m_targetTag = propertyValue.AsInt64();
        updateTargetElement = true;
      } else {
        m_targetTag = -1;
      }
    } else if (propertyName == "verticalOffset") {
      if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Double ||
          propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Int64)
        m_verticalOffset = propertyValue.AsSingle();
      else
        m_verticalOffset = 0;

      updateOffset = true;
    } else if (propertyName == "isOverlayEnabled") {
      auto overlayMode = winrt::LightDismissOverlayMode::Off;
      if (propertyValue.Type() == winrt::Microsoft::ReactNative::JSValueType::Boolean && propertyValue.AsBoolean()) {
        overlayMode = winrt::LightDismissOverlayMode::On;
      }

      m_flyout.LightDismissOverlayMode(overlayMode);
    } else if (propertyName == "autoFocus") {
      m_autoFocus = propertyValue.AsBoolean();
    } else if (propertyName == "showMode") {
      const auto showMode = json_type_traits<winrt::FlyoutShowMode>::parseJson(propertyValue);
      m_flyout.ShowMode(showMode);
      if (m_isFlyoutShowOptionsSupported) {
        m_showOptions.ShowMode(showMode);
      }
    } else if (propertyName == "shouldConstrainToRootBounds") {
      if (propertyValue.Type() == React::JSValueType::Boolean) {
        m_flyout.ShouldConstrainToRootBounds(propertyValue.AsBoolean());
      }
    }
  }

  if (updateTargetElement || m_targetElement == nullptr) {
    SetTargetFrameworkElement();
    winrt::FlyoutBase::SetAttachedFlyout(m_targetElement, m_flyout);
  }

  if (updateOffset && m_isFlyoutShowOptionsSupported) {
    winrt::Point newPoint(m_horizontalOffset, m_verticalOffset);
    m_showOptions.Position(newPoint);
  }

  if (updateIsOpen) {
    if (m_isOpen) {
      OnShowFlyout();
    } else {
      m_flyout.Hide();
    }
  }

  // TODO: hook up view props to the flyout (m_flyout) instead of setting them
  // on the dummy view.
  // Super::updateProperties(std::move(props));
  m_updating = false;
}