Skip to content

Commit 724a08c

Browse files
anupriya13acoates-ms
authored andcommitted
Implement onScrollBeginDrag property for ScrollView for fabric (microsoft#14446)
Implement onScrollBeginDrag property for ScrollView for fabric (microsoft#14446)
1 parent 2d5aa58 commit 724a08c

File tree

6 files changed

+59
-1
lines changed

6 files changed

+59
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "Implement OnScrollBeginDrag Event",
4+
"packageName": "react-native-windows",
5+
"email": "54227869+anupriya13@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}

packages/playground/Samples/scrollViewSnapSample.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,13 @@ export default class Bootstrap extends React.Component<{}, any> {
245245
snapToStart={this.state.snapToStartValue}
246246
snapToEnd={this.state.snapToEndValue}
247247
snapToAlignment={this.state.alignToStartValue ? 'start' : 'end'}
248-
horizontal={this.state.horizontalValue}>
248+
horizontal={this.state.horizontalValue}
249+
onScrollBeginDrag={() => {
250+
console.log('onScrollBeginDrag');
251+
}}
252+
onScroll={() => {
253+
console.log('onScroll');
254+
}}>
249255
{this.makeItems(20, [styles.itemWrapper])}
250256
</ScrollView>
251257
</View>

vnext/Microsoft.ReactNative/CompositionSwitcher.idl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ namespace Microsoft.ReactNative.Composition.Experimental
109109
void Brush(IBrush brush);
110110
void ScrollEnabled(Boolean isScrollEnabled);
111111
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollPositionChanged;
112+
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollBeginDrag;
112113
void ContentSize(Windows.Foundation.Numerics.Vector2 size);
113114
Windows.Foundation.Numerics.Vector3 ScrollPosition { get; };
114115
void ScrollBy(Windows.Foundation.Numerics.Vector3 offset, Boolean animate);

vnext/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,8 @@ struct CompScrollerVisual : winrt::implements<
708708
typename TTypeRedirects::InteractionTrackerInertiaStateEnteredArgs args) noexcept {
709709
m_outer->m_custom = false;
710710
m_outer->m_inertia = true;
711+
m_outer->m_currentPosition = args.NaturalRestingPosition();
712+
m_outer->FireScrollBeginDrag({args.NaturalRestingPosition().x, args.NaturalRestingPosition().y});
711713
}
712714
void InteractingStateEntered(
713715
typename TTypeRedirects::InteractionTracker sender,
@@ -918,10 +920,21 @@ struct CompScrollerVisual : winrt::implements<
918920
return m_scrollPositionChangedEvent.add(handler);
919921
}
920922

923+
winrt::event_token ScrollBeginDrag(
924+
winrt::Windows::Foundation::EventHandler<
925+
winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs> const
926+
&handler) noexcept {
927+
return m_scrollBeginDragEvent.add(handler);
928+
}
929+
921930
void ScrollPositionChanged(winrt::event_token const &token) noexcept {
922931
m_scrollPositionChangedEvent.remove(token);
923932
}
924933

934+
void ScrollBeginDrag(winrt::event_token const &token) noexcept {
935+
m_scrollBeginDragEvent.remove(token);
936+
}
937+
925938
void ContentSize(winrt::Windows::Foundation::Numerics::float2 const &size) noexcept {
926939
m_contentSize = size;
927940
m_contentVisual.Size(size);
@@ -992,6 +1005,10 @@ struct CompScrollerVisual : winrt::implements<
9921005
m_scrollPositionChangedEvent(*this, winrt::make<CompScrollPositionChangedArgs>(position));
9931006
}
9941007

1008+
void FireScrollBeginDrag(winrt::Windows::Foundation::Numerics::float2 position) noexcept {
1009+
m_scrollBeginDragEvent(*this, winrt::make<CompScrollPositionChangedArgs>(position));
1010+
}
1011+
9951012
void UpdateMaxPosition() noexcept {
9961013
m_interactionTracker.MaxPosition(
9971014
{std::max<float>(m_contentSize.x - m_visualSize.x, 0),
@@ -1010,6 +1027,9 @@ struct CompScrollerVisual : winrt::implements<
10101027
winrt::event<winrt::Windows::Foundation::EventHandler<
10111028
winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs>>
10121029
m_scrollPositionChangedEvent;
1030+
winrt::event<winrt::Windows::Foundation::EventHandler<
1031+
winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs>>
1032+
m_scrollBeginDragEvent;
10131033
typename TTypeRedirects::SpriteVisual m_visual{nullptr};
10141034
typename TTypeRedirects::SpriteVisual m_contentVisual{nullptr};
10151035
typename TTypeRedirects::InteractionTracker m_interactionTracker{nullptr};

vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,28 @@ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ScrollViewComp
12171217
->onScroll(scrollMetrics);
12181218
}
12191219
});
1220+
1221+
m_scrollBeginDragRevoker = m_scrollVisual.ScrollBeginDrag(
1222+
winrt::auto_revoke,
1223+
[this](
1224+
winrt::IInspectable const & /*sender*/,
1225+
winrt::Microsoft::ReactNative::Composition::Experimental::IScrollPositionChangedArgs const &args) {
1226+
updateStateWithContentOffset();
1227+
auto eventEmitter = GetEventEmitter();
1228+
if (eventEmitter) {
1229+
facebook::react::ScrollViewEventEmitter::Metrics scrollMetrics;
1230+
scrollMetrics.containerSize.height = m_layoutMetrics.frame.size.height;
1231+
scrollMetrics.containerSize.width = m_layoutMetrics.frame.size.width;
1232+
scrollMetrics.contentOffset.x = args.Position().x / m_layoutMetrics.pointScaleFactor;
1233+
scrollMetrics.contentOffset.y = args.Position().y / m_layoutMetrics.pointScaleFactor;
1234+
scrollMetrics.zoomScale = 1.0;
1235+
scrollMetrics.contentSize.height = std::max(m_contentSize.height, m_layoutMetrics.frame.size.height);
1236+
scrollMetrics.contentSize.width = std::max(m_contentSize.width, m_layoutMetrics.frame.size.width);
1237+
std::static_pointer_cast<facebook::react::ScrollViewEventEmitter const>(eventEmitter)
1238+
->onScrollBeginDrag(scrollMetrics);
1239+
}
1240+
});
1241+
12201242
return visual;
12211243
}
12221244

vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ struct ScrollInteractionTrackerOwner : public winrt::implements<
135135
std::shared_ptr<ScrollBarComponent> m_verticalScrollbarComponent{nullptr};
136136
winrt::Microsoft::ReactNative::Composition::Experimental::IScrollVisual::ScrollPositionChanged_revoker
137137
m_scrollPositionChangedRevoker{};
138+
winrt::Microsoft::ReactNative::Composition::Experimental::IScrollVisual::ScrollBeginDrag_revoker
139+
m_scrollBeginDragRevoker{};
138140

139141
float m_zoomFactor{1.0f};
140142
bool m_isScrollingFromInertia = false;

0 commit comments

Comments
 (0)