Skip to content

Commit 61c8174

Browse files
Nitin-100Nitin Chaudharyvineethkuttan
authored
Props parity work from paper to fabric. (#15406)
* ContextMenu implementation in Fabric as per Parity to Paper (#15339) * Change files * Implement context menu support for Fabric TextInput with contextMenuHidden property * Fix beachball change file - add meaningful comment * Fix context menu Paste option to check clipboard content - Added clipboard content check using IsClipboardFormatAvailable(CF_UNICODETEXT) - Paste menu item now only enabled when clipboard has text AND field is editable - Fixes bug where Cut/Copy/Paste showed even when text field was empty - Matches XAML TextBox automatic clipboard state checking behavior Menu item logic now matches Paper: - Cut: requires selection AND editable - Copy: requires selection only - Paste: requires editable AND clipboard has text content - Select All: requires non-empty text AND editable * Fix context menu to show on button release (WM_RBUTTONUP) instead of press --------- Co-authored-by: Nitin Chaudhary <nitchaudhary@microsoft.com> * TextAlign and WritingDirection Parity for Fabric TextInput (#15340) * Change files * Implement textAlign justify and writingDirection support in Fabric TextInput - Add support for textAlign='justify' using PFA_JUSTIFY flag - Implement writingDirection (baseWritingDirection) support for 'ltr', 'rtl', and 'auto' - Make textAlign='auto' (Natural) respect RTL writing direction - Set PFM_RTLPARA and PFE_RTLPARA flags for RTL text - Achieves full parity with Paper XAML implementation * Fix beachball change file - add meaningful comment * Add textAlign and writingDirection support to TextInput and text layout - TextInput now properly handles textAlign (Left, Right, Center, Justified, Natural) - TextInput now properly handles writingDirection/baseWritingDirection (LTR, RTL, Natural) - WritingDirection::Natural uses layoutMetrics.layoutDirection since direction can be overridden at any point in the tree - Added matching support in WindowsTextLayoutManager for text measurement - WindowsTextLayoutManager now sets DWRITE_READING_DIRECTION based on baseWritingDirection - TextAlignment::Natural now respects reading direction (RTL = trailing, LTR = leading) - Fixes layout affecting flags that impact text measurement throughout the system * Fix reading direction to only apply when explicitly set - Only call SetReadingDirection when baseWritingDirection is explicitly specified - Avoids breaking existing text layouts that don't specify writingDirection - Fixes LegacyControlStyleTest snapshot failure - Natural alignment still respects RTL when baseWritingDirection is set --------- Co-authored-by: Nitin Chaudhary <nitchaudhary@microsoft.com> * PagingEnabled Parity for Fabric ScrollView (#15341) * Implement pagingEnabled prop for Fabric ScrollView - Add pagingEnabled boolean member to CompScrollerVisual - Implement PagingEnabled() method in IScrollVisual interface - Generate viewport-sized snap points when pagingEnabled=true - Wire up pagingEnabled prop in ScrollViewComponentView::updateProps() - Achieves parity with Paper ScrollView pagingEnabled support * Implement pagingEnabled property for Fabric ScrollView - Added bool m_pagingEnabled member to CompScrollerVisual - Implemented PagingEnabled() method in IScrollVisual interface - Generate viewport-sized snap points when pagingEnabled=true - Wired up prop handling in ScrollViewComponentView - snapToOffsets disables pagingEnabled (matches Paper/iOS/Android behavior) - Excludes snapToEnd when pagingEnabled to avoid conflicts - Validates viewport size before generating snap points - Reconfigures snap points when size changes and paging is enabled Achieves full parity with Paper XAML and cross-platform React Native behavior. * Implement snapToInterval and snapToAlignment for Fabric ScrollView Added complete snap point parity with Paper/iOS/Android: 1. pagingEnabled: Snaps to viewport-size intervals - Already implemented in previous commit - Full page-by-page scrolling behavior 2. snapToInterval: Snaps to fixed interval multiples - More flexible than pagingEnabled - Works with any interval value - Generates snap points at: 0, interval, 2*interval, 3*interval, ... maxScroll 3. snapToAlignment: Controls snap point alignment - Values: 'start' (Near), 'center' (Center), 'end' (Far) - Only applies when snapToInterval is set - Start: no offset (default) - Center: offset = -viewport/2 - End: offset = -viewport Priority hierarchy matches React Native official behavior: - snapToOffsets (highest) > snapToInterval > pagingEnabled > snapToStart/snapToEnd Implementation: - Added SnapPointsAlignment enum to CompositionSwitcher.idl - Added m_snapToInterval and m_snapToAlignment members to CompScrollerVisual - Implemented SnapToInterval() and SnapToAlignment() methods - Updated ConfigureSnapInertiaModifiers() with priority-based snap point generation - Wired props in ScrollViewComponentView::updateProps() - snapToOffsets disables both snapToInterval and pagingEnabled Matches Paper's SnapPointManagingContentControl behavior where: - GetRegularSnapPoints() returns m_interval when set - SnapToOffsets() sets m_interval = 0 (disables it) - XAML SnapPointsAlignment maps to: Near=start, Center=center, Far=end * Fix snapToInterval type - Float not optional * Update change file and fix formatting for snap point implementation --------- Co-authored-by: Nitin Chaudhary <nitchaudhary@microsoft.com> --------- Co-authored-by: Nitin Chaudhary <nitchaudhary@microsoft.com> Co-authored-by: Vineeth <66076509+vineethkuttan@users.noreply.github.com>
1 parent 71b89a7 commit 61c8174

9 files changed

+431
-186
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"comment": "Implement textAlign justify and writingDirection support (ltr/rtl/auto) for Fabric TextInput",
3+
"type": "prerelease",
4+
"packageName": "react-native-windows",
5+
"email": "nitchaudhary@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"comment": "Implement context menu support for Fabric TextInput with Cut, Copy, Paste, and Select All options",
3+
"type": "prerelease",
4+
"packageName": "react-native-windows",
5+
"email": "nitchaudhary@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}
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 snap point parity for Fabric ScrollView: pagingEnabled (viewport-sized intervals), snapToInterval (custom interval snapping), and snapToAlignment (start/center/end alignment) matching iOS/Android/Paper behavior with priority hierarchy snapToOffsets > snapToInterval > pagingEnabled",
4+
"packageName": "react-native-windows",
5+
"email": "nitinkum@microsoft.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 163 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -1,178 +1,179 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
#include "NamespaceRedirect.h"
54
#include "DocString.h"
5+
#include "NamespaceRedirect.h"
66
import "Composition.Input.idl";
77

8-
namespace Microsoft.ReactNative.Composition.Experimental
8+
namespace Microsoft.ReactNative.Composition.Experimental {
9+
enum CompositionStretch {
10+
None,
11+
Fill,
12+
Uniform,
13+
UniformToFill,
14+
};
15+
16+
enum BackfaceVisibility { Inherit, Visible, Hidden };
17+
18+
enum AnimationClass {
19+
None = 0,
20+
ScrollBar,
21+
ScrollBarThumbHorizontal,
22+
ScrollBarThumbVertical,
23+
SwitchThumb,
24+
};
25+
26+
enum SnapPointsAlignment {
27+
Near = 0, // Start alignment (left/top)
28+
Center = 1, // Center alignment
29+
Far = 2, // End alignment (right/bottom)
30+
};
31+
32+
[webhosthidden][uuid("172def51-9e1a-4e3c-841a-e5a470065acc")] // uuid needed for empty interfaces
33+
[version(0)][experimental] interface IBrush {}
34+
35+
[webhosthidden][experimental] interface IDrawingSurfaceBrush
36+
requires IBrush
37+
{
38+
void HorizontalAlignmentRatio(Single value);
39+
void VerticalAlignmentRatio(Single value);
40+
void Stretch(CompositionStretch value);
41+
}
42+
43+
[webhosthidden][experimental] interface IDropShadow {
44+
void Offset(Windows.Foundation.Numerics.Vector3 value);
45+
void Opacity(Single value);
46+
void BlurRadius(Single value);
47+
void Color(Windows.UI.Color value);
48+
}
49+
50+
[webhosthidden][experimental] interface IVisual {
51+
void InsertAt(IVisual visual, Int32 index);
52+
void Remove(IVisual visual);
53+
IVisual GetAt(UInt32 index);
54+
void Opacity(Single opacity);
55+
void Scale(Windows.Foundation.Numerics.Vector3 scale);
56+
void TransformMatrix(Windows.Foundation.Numerics.Matrix4x4 transform);
57+
void RotationAngle(Single angle);
58+
void IsVisible(Boolean isVisible);
59+
void Size(Windows.Foundation.Numerics.Vector2 size);
60+
void Offset(Windows.Foundation.Numerics.Vector3 offset);
61+
void Offset(Windows.Foundation.Numerics.Vector3 offset, Windows.Foundation.Numerics.Vector3 relativeAdjustment);
62+
void RelativeSizeWithOffset(
63+
Windows.Foundation.Numerics.Vector2 size, Windows.Foundation.Numerics.Vector2 relativeSizeAdjustment);
64+
BackfaceVisibility BackfaceVisibility {
65+
get;
66+
set;
67+
};
68+
String Comment {
69+
get;
70+
set;
71+
};
72+
void AnimationClass(AnimationClass value);
73+
}
74+
75+
[webhosthidden][experimental] interface ISpriteVisual
76+
requires IVisual
77+
{
78+
void Brush(IBrush brush);
79+
void Shadow(IDropShadow shadow);
80+
}
81+
82+
[webhosthidden][experimental] interface IRoundedRectangleVisual
83+
requires IVisual
984
{
10-
enum CompositionStretch
11-
{
12-
None,
13-
Fill,
14-
Uniform,
15-
UniformToFill,
85+
void Brush(IBrush brush);
86+
void CornerRadius(Windows.Foundation.Numerics.Vector2 value);
87+
void StrokeBrush(IBrush brush);
88+
void StrokeThickness(Single value);
89+
}
90+
91+
[webhosthidden][experimental] interface IScrollPositionChangedArgs {
92+
Windows.Foundation.Numerics.Vector2 Position {
93+
get;
1694
};
95+
}
1796

18-
enum BackfaceVisibility
19-
{
20-
Inherit,
21-
Visible,
22-
Hidden
97+
[webhosthidden][experimental] interface IScrollVisual
98+
requires IVisual
99+
{
100+
void Brush(IBrush brush);
101+
void ScrollEnabled(Boolean isScrollEnabled);
102+
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollPositionChanged;
103+
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollBeginDrag;
104+
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollEndDrag;
105+
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollMomentumBegin;
106+
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollMomentumEnd;
107+
void ContentSize(Windows.Foundation.Numerics.Vector2 size);
108+
Windows.Foundation.Numerics.Vector3 ScrollPosition {
109+
get;
110+
};
111+
void ScrollBy(Windows.Foundation.Numerics.Vector3 offset, Boolean animate);
112+
void TryUpdatePosition(Windows.Foundation.Numerics.Vector3 position, Boolean animate);
113+
void OnPointerPressed(Microsoft.ReactNative.Composition.Input.PointerRoutedEventArgs args);
114+
void SetDecelerationRate(Windows.Foundation.Numerics.Vector3 decelerationRate);
115+
void SetMaximumZoomScale(Single maximumZoomScale);
116+
void SetMinimumZoomScale(Single minimumZoomScale);
117+
Boolean Horizontal;
118+
void SetSnapPoints(
119+
Boolean snapToStart, Boolean snapToEnd, Windows.Foundation.Collections.IVectorView<Single> offsets);
120+
void PagingEnabled(Boolean pagingEnabled);
121+
void SnapToInterval(Single interval);
122+
void SnapToAlignment(SnapPointsAlignment alignment);
123+
}
124+
125+
[webhosthidden][experimental] interface IActivityVisual
126+
requires IVisual
127+
{
128+
void Size(Single value);
129+
void Brush(IBrush brush);
130+
void StartAnimation();
131+
void StopAnimation();
132+
}
133+
134+
[webhosthidden][experimental] interface ICaretVisual {
135+
IVisual InnerVisual {
136+
get;
23137
};
24-
25-
enum AnimationClass
26-
{
27-
None = 0,
28-
ScrollBar,
29-
ScrollBarThumbHorizontal,
30-
ScrollBarThumbVertical,
31-
SwitchThumb,
138+
void Size(Windows.Foundation.Numerics.Vector2 size);
139+
void Position(Windows.Foundation.Numerics.Vector2 position);
140+
Boolean IsVisible {
141+
get;
142+
set;
32143
};
144+
void Brush(IBrush brush);
145+
}
33146

34-
[webhosthidden]
35-
[uuid("172def51-9e1a-4e3c-841a-e5a470065acc")] // uuid needed for empty interfaces
36-
[version(0)]
37-
[experimental]
38-
interface IBrush {
39-
}
40-
41-
[webhosthidden]
42-
[experimental]
43-
interface IDrawingSurfaceBrush requires IBrush
44-
{
45-
void HorizontalAlignmentRatio(Single value);
46-
void VerticalAlignmentRatio(Single value);
47-
void Stretch(CompositionStretch value);
48-
}
49-
50-
[webhosthidden]
51-
[experimental]
52-
interface IDropShadow {
53-
void Offset(Windows.Foundation.Numerics.Vector3 value);
54-
void Opacity(Single value);
55-
void BlurRadius(Single value);
56-
void Color(Windows.UI.Color value);
57-
}
58-
59-
[webhosthidden]
60-
[experimental]
61-
interface IVisual
62-
{
63-
void InsertAt(IVisual visual, Int32 index);
64-
void Remove(IVisual visual);
65-
IVisual GetAt(UInt32 index);
66-
void Opacity(Single opacity);
67-
void Scale(Windows.Foundation.Numerics.Vector3 scale);
68-
void TransformMatrix(Windows.Foundation.Numerics.Matrix4x4 transform);
69-
void RotationAngle(Single angle);
70-
void IsVisible(Boolean isVisible);
71-
void Size(Windows.Foundation.Numerics.Vector2 size);
72-
void Offset(Windows.Foundation.Numerics.Vector3 offset);
73-
void Offset(Windows.Foundation.Numerics.Vector3 offset, Windows.Foundation.Numerics.Vector3 relativeAdjustment);
74-
void RelativeSizeWithOffset(Windows.Foundation.Numerics.Vector2 size, Windows.Foundation.Numerics.Vector2 relativeSizeAdjustment);
75-
BackfaceVisibility BackfaceVisibility{ get; set; };
76-
String Comment { get; set; };
77-
void AnimationClass(AnimationClass value);
78-
}
79-
80-
[webhosthidden]
81-
[experimental]
82-
interface ISpriteVisual requires IVisual
83-
{
84-
void Brush(IBrush brush);
85-
void Shadow(IDropShadow shadow);
86-
}
87-
88-
[webhosthidden]
89-
[experimental]
90-
interface IRoundedRectangleVisual requires IVisual
91-
{
92-
void Brush(IBrush brush);
93-
void CornerRadius(Windows.Foundation.Numerics.Vector2 value);
94-
void StrokeBrush(IBrush brush);
95-
void StrokeThickness(Single value);
96-
}
97-
98-
[webhosthidden]
99-
[experimental]
100-
interface IScrollPositionChangedArgs
101-
{
102-
Windows.Foundation.Numerics.Vector2 Position { get; };
103-
}
104-
105-
[webhosthidden]
106-
[experimental]
107-
interface IScrollVisual requires IVisual
108-
{
109-
void Brush(IBrush brush);
110-
void ScrollEnabled(Boolean isScrollEnabled);
111-
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollPositionChanged;
112-
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollBeginDrag;
113-
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollEndDrag;
114-
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollMomentumBegin;
115-
event Windows.Foundation.EventHandler<IScrollPositionChangedArgs> ScrollMomentumEnd;
116-
void ContentSize(Windows.Foundation.Numerics.Vector2 size);
117-
Windows.Foundation.Numerics.Vector3 ScrollPosition { get; };
118-
void ScrollBy(Windows.Foundation.Numerics.Vector3 offset, Boolean animate);
119-
void TryUpdatePosition(Windows.Foundation.Numerics.Vector3 position, Boolean animate);
120-
void OnPointerPressed(Microsoft.ReactNative.Composition.Input.PointerRoutedEventArgs args);
121-
void SetDecelerationRate(Windows.Foundation.Numerics.Vector3 decelerationRate);
122-
void SetMaximumZoomScale(Single maximumZoomScale);
123-
void SetMinimumZoomScale(Single minimumZoomScale);
124-
Boolean Horizontal;
125-
void SetSnapPoints(Boolean snapToStart, Boolean snapToEnd, Windows.Foundation.Collections.IVectorView<Single> offsets);
126-
}
127-
128-
[webhosthidden]
129-
[experimental]
130-
interface IActivityVisual requires IVisual
131-
{
132-
void Size(Single value);
133-
void Brush(IBrush brush);
134-
void StartAnimation();
135-
void StopAnimation();
136-
}
137-
138-
[webhosthidden]
139-
[experimental]
140-
interface ICaretVisual
141-
{
142-
IVisual InnerVisual { get; };
143-
void Size(Windows.Foundation.Numerics.Vector2 size);
144-
void Position(Windows.Foundation.Numerics.Vector2 position);
145-
Boolean IsVisible { get; set; };
146-
void Brush(IBrush brush);
147-
}
148-
149-
[webhosthidden]
150-
[experimental]
151-
interface IFocusVisual
152-
{
153-
IVisual InnerVisual { get; };
154-
Boolean IsFocused { get; set; };
155-
Single ScaleFactor { get; set; };
156-
}
157-
158-
[webhosthidden]
159-
[experimental]
160-
interface ICompositionContext
161-
{
162-
ISpriteVisual CreateSpriteVisual();
163-
IScrollVisual CreateScrollerVisual();
164-
IRoundedRectangleVisual CreateRoundedRectangleVisual();
165-
IActivityVisual CreateActivityVisual();
166-
ICaretVisual CreateCaretVisual();
167-
IFocusVisual CreateFocusVisual();
168-
IDropShadow CreateDropShadow();
169-
IBrush CreateColorBrush(Windows.UI.Color color);
170-
IDrawingSurfaceBrush CreateDrawingSurfaceBrush(Windows.Foundation.Size surfaceSize,
147+
[webhosthidden][experimental] interface IFocusVisual {
148+
IVisual InnerVisual {
149+
get;
150+
};
151+
Boolean IsFocused {
152+
get;
153+
set;
154+
};
155+
Single ScaleFactor {
156+
get;
157+
set;
158+
};
159+
}
160+
161+
[webhosthidden][experimental] interface ICompositionContext {
162+
ISpriteVisual CreateSpriteVisual();
163+
IScrollVisual CreateScrollerVisual();
164+
IRoundedRectangleVisual CreateRoundedRectangleVisual();
165+
IActivityVisual CreateActivityVisual();
166+
ICaretVisual CreateCaretVisual();
167+
IFocusVisual CreateFocusVisual();
168+
IDropShadow CreateDropShadow();
169+
IBrush CreateColorBrush(Windows.UI.Color color);
170+
IDrawingSurfaceBrush CreateDrawingSurfaceBrush(
171+
Windows.Foundation.Size surfaceSize,
171172
Windows.Graphics.DirectX.DirectXPixelFormat pixelFormat,
172173
Windows.Graphics.DirectX.DirectXAlphaMode alphaMode);
173174

174-
// TODO Add and hook up to rootnode - to notify the tree
175-
// event Windows.Foundation.EventHandler<RenderingDeviceReplacedArgs> RenderingDeviceReplaced;
176-
}
175+
// TODO Add and hook up to rootnode - to notify the tree
176+
// event Windows.Foundation.EventHandler<RenderingDeviceReplacedArgs> RenderingDeviceReplaced;
177+
}
177178

178-
} // namespace Microsoft.ReactNative.Composition.Experimental
179+
} // namespace Microsoft.ReactNative.Composition. Experimental

0 commit comments

Comments
 (0)