react-native-windows 0.75.5 → 0.75.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js +15 -15
- package/Libraries/Components/Button.windows.js +18 -18
- package/Libraries/Components/Flyout/FlyoutNativeComponent.js +5 -1
- package/Libraries/Components/TextInput/TextInput.windows.js +14 -10
- package/Libraries/Components/Touchable/Touchable.windows.js +2 -2
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +5 -3
- package/Libraries/Text/Text.windows.js +2 -2
- package/Libraries/Utilities/Platform.windows.js +4 -4
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +12 -0
- package/Microsoft.ReactNative/Fabric/ComponentView.h +3 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +70 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +8 -2
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +24 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +8 -3
- package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +1 -0
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +11 -0
- package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.cpp +1 -2
- package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.h +1 -1
- package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +12 -4
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +338 -0
- package/Microsoft.ReactNative/Fabric/Composition/TooltipService.h +66 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +8 -0
- package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +1 -0
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +3 -0
- package/Microsoft.ReactNative/Fabric/ReactTaggedView.h +4 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +5 -0
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +1 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewTraitsInitializer.h +1 -1
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -1
- package/Microsoft.ReactNative/ReactCoreInjection.h +0 -1
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Shared.vcxitems +3 -0
- package/Shared/Shared.vcxitems.filters +2 -0
- package/just-task.js +1 -1
- package/package.json +3 -4
- package/templates/cpp-app/template.config.js +8 -3
- package/templates/cpp-lib/template.config.js +8 -3
- package/templates/templateUtils.js +2 -3
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
|
|
5
|
+
#include "TooltipService.h"
|
|
6
|
+
|
|
7
|
+
#include <CompositionSwitcher.Experimental.interop.h>
|
|
8
|
+
#include <Fabric/Composition/CompositionViewComponentView.h>
|
|
9
|
+
#include <react/renderer/attributedstring/AttributedStringBox.h>
|
|
10
|
+
#include <react/renderer/core/LayoutConstraints.h>
|
|
11
|
+
#include <react/renderer/textlayoutmanager/TextLayoutManager.h>
|
|
12
|
+
#include <winrt/Microsoft.ReactNative.Composition.h>
|
|
13
|
+
#include "TextDrawing.h"
|
|
14
|
+
#include "dwmapi.h"
|
|
15
|
+
|
|
16
|
+
namespace winrt::Microsoft::ReactNative {
|
|
17
|
+
|
|
18
|
+
constexpr PCWSTR c_tooltipWindowClassName = L"RN_TOOLTIP";
|
|
19
|
+
constexpr auto TooltipDataProperty = L"TooltipData";
|
|
20
|
+
constexpr float tooltipFontSize = 12;
|
|
21
|
+
constexpr float tooltipMaxHeight = 1000;
|
|
22
|
+
constexpr float tooltipMaxWidth = 320;
|
|
23
|
+
constexpr float tooltipHorizontalPadding = 8;
|
|
24
|
+
constexpr float tooltipTopPadding = 5;
|
|
25
|
+
constexpr float tooltipBottomPadding = 7;
|
|
26
|
+
constexpr float toolTipBorderThickness = 1;
|
|
27
|
+
constexpr int toolTipPlacementMargin = 12;
|
|
28
|
+
constexpr int toolTipAnimationTimeMs = 200;
|
|
29
|
+
constexpr int toolTipTimeToShowMs = 1000;
|
|
30
|
+
|
|
31
|
+
struct TooltipData {
|
|
32
|
+
TooltipData(const winrt::Microsoft::ReactNative::ComponentView &view) : view(view) {}
|
|
33
|
+
|
|
34
|
+
static TooltipData *GetFromWindow(HWND hwnd) {
|
|
35
|
+
auto data = reinterpret_cast<TooltipData *>(GetProp(hwnd, TooltipDataProperty));
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
int width;
|
|
40
|
+
int height;
|
|
41
|
+
::Microsoft::ReactNative::ReactTaggedView view;
|
|
42
|
+
winrt::com_ptr<::IDWriteTextLayout> textLayout;
|
|
43
|
+
facebook::react::AttributedStringBox attributedString;
|
|
44
|
+
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext compositionContext;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
facebook::react::AttributedStringBox CreateTooltipAttributedString(const std::string &tooltip) noexcept {
|
|
48
|
+
auto attributedString = facebook::react::AttributedString{};
|
|
49
|
+
auto fragment = facebook::react::AttributedString::Fragment{};
|
|
50
|
+
fragment.string = tooltip;
|
|
51
|
+
fragment.textAttributes.fontSize = tooltipFontSize;
|
|
52
|
+
attributedString.appendFragment(fragment);
|
|
53
|
+
return facebook::react::AttributedStringBox{attributedString};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
LRESULT CALLBACK TooltipWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) noexcept {
|
|
57
|
+
switch (message) {
|
|
58
|
+
case WM_DESTROY: {
|
|
59
|
+
delete TooltipData::GetFromWindow(hwnd);
|
|
60
|
+
SetProp(hwnd, TooltipDataProperty, 0);
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
case WM_PRINTCLIENT:
|
|
64
|
+
case WM_PAINT: {
|
|
65
|
+
HDC hdc;
|
|
66
|
+
PAINTSTRUCT ps;
|
|
67
|
+
|
|
68
|
+
if (message != WM_PRINTCLIENT)
|
|
69
|
+
hdc = BeginPaint(hwnd, &ps);
|
|
70
|
+
else
|
|
71
|
+
hdc = (HDC)wparam;
|
|
72
|
+
auto data = TooltipData::GetFromWindow(hwnd);
|
|
73
|
+
|
|
74
|
+
if (auto view = data->view.view()) {
|
|
75
|
+
auto scaleFactor = view.LayoutMetrics().PointScaleFactor;
|
|
76
|
+
|
|
77
|
+
auto ccInterop = data->compositionContext
|
|
78
|
+
.as<::Microsoft::ReactNative::Composition::Experimental::ICompositionContextInterop>();
|
|
79
|
+
winrt::com_ptr<ID2D1Factory1> factory;
|
|
80
|
+
ccInterop->D2DFactory(factory.put());
|
|
81
|
+
|
|
82
|
+
winrt::com_ptr<ID2D1DCRenderTarget> renderTarget;
|
|
83
|
+
|
|
84
|
+
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
|
|
85
|
+
D2D1_RENDER_TARGET_TYPE_DEFAULT,
|
|
86
|
+
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE),
|
|
87
|
+
0,
|
|
88
|
+
0,
|
|
89
|
+
D2D1_RENDER_TARGET_USAGE_NONE,
|
|
90
|
+
D2D1_FEATURE_LEVEL_DEFAULT);
|
|
91
|
+
winrt::check_hresult(factory->CreateDCRenderTarget(&props, renderTarget.put()));
|
|
92
|
+
RECT rc;
|
|
93
|
+
GetClientRect(hwnd, &rc);
|
|
94
|
+
winrt::check_hresult(renderTarget->BindDC(hdc, &rc));
|
|
95
|
+
auto theme = view.as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Theme();
|
|
96
|
+
auto selfTheme = winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::Theme>(theme);
|
|
97
|
+
|
|
98
|
+
renderTarget->BeginDraw();
|
|
99
|
+
renderTarget->Clear(selfTheme->D2DPlatformColor("ToolTipBackground"));
|
|
100
|
+
|
|
101
|
+
auto textAttributes = facebook::react::TextAttributes{};
|
|
102
|
+
facebook::react::Color fgColor;
|
|
103
|
+
fgColor.m_platformColor.push_back("ToolTipForeground");
|
|
104
|
+
textAttributes.foregroundColor = fgColor;
|
|
105
|
+
|
|
106
|
+
winrt::Microsoft::ReactNative::Composition::RenderText(
|
|
107
|
+
*renderTarget,
|
|
108
|
+
*data->textLayout,
|
|
109
|
+
data->attributedString.getValue(),
|
|
110
|
+
textAttributes,
|
|
111
|
+
{std::round(tooltipHorizontalPadding * scaleFactor), std::round(tooltipTopPadding * scaleFactor)},
|
|
112
|
+
scaleFactor,
|
|
113
|
+
*selfTheme);
|
|
114
|
+
|
|
115
|
+
auto hr = renderTarget->EndDraw();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (message != WM_PRINTCLIENT)
|
|
119
|
+
EndPaint(hwnd, &ps);
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
case WM_NCCREATE: {
|
|
123
|
+
auto cs = reinterpret_cast<CREATESTRUCT *>(lparam);
|
|
124
|
+
auto data = static_cast<TooltipData *>(cs->lpCreateParams);
|
|
125
|
+
WINRT_ASSERT(data);
|
|
126
|
+
SetProp(hwnd, TooltipDataProperty, reinterpret_cast<HANDLE>(data));
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return DefWindowProc(hwnd, message, wparam, lparam);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
void RegisterTooltipWndClass() noexcept {
|
|
135
|
+
static bool registered = false;
|
|
136
|
+
if (registered) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
HINSTANCE hInstance =
|
|
141
|
+
GetModuleHandle(NULL); // returns a handle to the file used to create the calling process (.exe file)
|
|
142
|
+
|
|
143
|
+
WNDCLASSEX wcex = {}; // contains window class information
|
|
144
|
+
wcex.cbSize = sizeof(wcex); // size of windows class (bytes)
|
|
145
|
+
wcex.style = CS_HREDRAW | CS_VREDRAW; // class style (redraw window on size adjustment)
|
|
146
|
+
wcex.lpfnWndProc = &TooltipWndProc; // pointer to windows procedure
|
|
147
|
+
wcex.cbClsExtra = DLGWINDOWEXTRA; // extra bytes to allocate
|
|
148
|
+
wcex.cbWndExtra = sizeof(TooltipData *); // extra bytes to allocate
|
|
149
|
+
wcex.hInstance = hInstance;
|
|
150
|
+
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); // handle to class cursor
|
|
151
|
+
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // background color
|
|
152
|
+
wcex.lpszClassName = c_tooltipWindowClassName; // specify resource name
|
|
153
|
+
ATOM classId = RegisterClassEx(&wcex); // register new windows class
|
|
154
|
+
WINRT_VERIFY(classId); // 0 = fail
|
|
155
|
+
winrt::check_win32(!classId);
|
|
156
|
+
|
|
157
|
+
registered = true;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
TooltipTracker::TooltipTracker(
|
|
161
|
+
const winrt::Microsoft::ReactNative::ComponentView &view,
|
|
162
|
+
const winrt::Microsoft::ReactNative::ReactPropertyBag &properties,
|
|
163
|
+
TooltipService *outer)
|
|
164
|
+
: m_view(view), m_properties(properties), m_outer(outer) {
|
|
165
|
+
view.PointerEntered({this, &TooltipTracker::OnPointerEntered});
|
|
166
|
+
view.PointerExited({this, &TooltipTracker::OnPointerExited});
|
|
167
|
+
view.PointerMoved({this, &TooltipTracker::OnPointerMoved});
|
|
168
|
+
view.Unmounted({this, &TooltipTracker::OnUnmounted});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
TooltipTracker::~TooltipTracker() {
|
|
172
|
+
DestroyTimer();
|
|
173
|
+
DestroyTooltip();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
facebook::react::Tag TooltipTracker::Tag() const noexcept {
|
|
177
|
+
return m_view.Tag();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
void TooltipTracker::OnPointerEntered(
|
|
181
|
+
const winrt::Windows::Foundation::IInspectable &sender,
|
|
182
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept {
|
|
183
|
+
if (args.Pointer().PointerDeviceType() !=
|
|
184
|
+
winrt::Microsoft::ReactNative::Composition::Input::PointerDeviceType::Mouse &&
|
|
185
|
+
args.Pointer().PointerDeviceType() != winrt::Microsoft::ReactNative::Composition::Input::PointerDeviceType::Pen)
|
|
186
|
+
return;
|
|
187
|
+
|
|
188
|
+
auto pp = args.GetCurrentPoint(-1);
|
|
189
|
+
m_pos = pp.Position();
|
|
190
|
+
|
|
191
|
+
m_timer = winrt::Microsoft::ReactNative::Timer::Create(m_properties.Handle());
|
|
192
|
+
m_timer.Interval(std::chrono::milliseconds(toolTipTimeToShowMs));
|
|
193
|
+
m_timer.Tick({this, &TooltipTracker::OnTick});
|
|
194
|
+
m_timer.Start();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
void TooltipTracker::OnPointerMoved(
|
|
198
|
+
const winrt::Windows::Foundation::IInspectable &sender,
|
|
199
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept {
|
|
200
|
+
if (args.Pointer().PointerDeviceType() !=
|
|
201
|
+
winrt::Microsoft::ReactNative::Composition::Input::PointerDeviceType::Mouse &&
|
|
202
|
+
args.Pointer().PointerDeviceType() != winrt::Microsoft::ReactNative::Composition::Input::PointerDeviceType::Pen)
|
|
203
|
+
return;
|
|
204
|
+
|
|
205
|
+
auto pp = args.GetCurrentPoint(-1);
|
|
206
|
+
m_pos = pp.Position();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
void TooltipTracker::OnTick(
|
|
210
|
+
const winrt::Windows::Foundation::IInspectable &,
|
|
211
|
+
const winrt::Windows::Foundation::IInspectable &) noexcept {
|
|
212
|
+
ShowTooltip(m_view.view());
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
void TooltipTracker::OnPointerExited(
|
|
216
|
+
const winrt::Windows::Foundation::IInspectable &sender,
|
|
217
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept {
|
|
218
|
+
if (args.Pointer().PointerDeviceType() !=
|
|
219
|
+
winrt::Microsoft::ReactNative::Composition::Input::PointerDeviceType::Mouse &&
|
|
220
|
+
args.Pointer().PointerDeviceType() != winrt::Microsoft::ReactNative::Composition::Input::PointerDeviceType::Pen)
|
|
221
|
+
return;
|
|
222
|
+
DestroyTimer();
|
|
223
|
+
DestroyTooltip();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
void TooltipTracker::OnUnmounted(
|
|
227
|
+
const winrt::Windows::Foundation::IInspectable &,
|
|
228
|
+
const winrt::Microsoft::ReactNative::ComponentView &) noexcept {
|
|
229
|
+
DestroyTimer();
|
|
230
|
+
DestroyTooltip();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
void TooltipTracker::ShowTooltip(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
|
|
234
|
+
auto viewCompView = view.as<winrt::Microsoft::ReactNative::Composition::ViewComponentView>();
|
|
235
|
+
|
|
236
|
+
auto selfView =
|
|
237
|
+
winrt::get_self<winrt::Microsoft::ReactNative::Composition::implementation::ViewComponentView>(viewCompView);
|
|
238
|
+
auto parentHwnd = selfView->GetHwndForParenting();
|
|
239
|
+
DestroyTimer();
|
|
240
|
+
|
|
241
|
+
if (!m_hwndTip) {
|
|
242
|
+
auto tooltipData = std::make_unique<TooltipData>(view);
|
|
243
|
+
tooltipData->attributedString = CreateTooltipAttributedString(*selfView->viewProps()->tooltip);
|
|
244
|
+
|
|
245
|
+
tooltipData->compositionContext = selfView->CompositionContext();
|
|
246
|
+
tooltipData->view = view;
|
|
247
|
+
|
|
248
|
+
auto scaleFactor = view.LayoutMetrics().PointScaleFactor;
|
|
249
|
+
facebook::react::LayoutConstraints layoutConstraints;
|
|
250
|
+
layoutConstraints.layoutDirection = facebook::react::LayoutDirection::Undefined;
|
|
251
|
+
layoutConstraints.maximumSize.height = tooltipMaxHeight * scaleFactor;
|
|
252
|
+
layoutConstraints.maximumSize.width = tooltipMaxWidth * scaleFactor;
|
|
253
|
+
layoutConstraints.minimumSize.height = 0;
|
|
254
|
+
layoutConstraints.minimumSize.width = 0;
|
|
255
|
+
|
|
256
|
+
facebook::react::TextLayoutManager::GetTextLayout(
|
|
257
|
+
tooltipData->attributedString, {} /*paragraphAttributes*/, layoutConstraints, tooltipData->textLayout);
|
|
258
|
+
|
|
259
|
+
DWRITE_TEXT_METRICS tm;
|
|
260
|
+
winrt::check_hresult(tooltipData->textLayout->GetMetrics(&tm));
|
|
261
|
+
|
|
262
|
+
tooltipData->width =
|
|
263
|
+
static_cast<int>(tm.width + ((tooltipHorizontalPadding + tooltipHorizontalPadding) * scaleFactor));
|
|
264
|
+
tooltipData->height = static_cast<int>(tm.height + ((tooltipTopPadding + tooltipBottomPadding) * scaleFactor));
|
|
265
|
+
|
|
266
|
+
POINT pt = {static_cast<LONG>(m_pos.X), static_cast<LONG>(m_pos.Y)};
|
|
267
|
+
ClientToScreen(parentHwnd, &pt);
|
|
268
|
+
|
|
269
|
+
RegisterTooltipWndClass();
|
|
270
|
+
HINSTANCE hInstance = GetModuleHandle(NULL);
|
|
271
|
+
m_hwndTip = CreateWindow(
|
|
272
|
+
c_tooltipWindowClassName,
|
|
273
|
+
L"Tooltip",
|
|
274
|
+
WS_POPUP,
|
|
275
|
+
pt.x - tooltipData->width / 2,
|
|
276
|
+
static_cast<int>(pt.y - tooltipData->height - (toolTipPlacementMargin * scaleFactor)),
|
|
277
|
+
tooltipData->width,
|
|
278
|
+
tooltipData->height,
|
|
279
|
+
parentHwnd,
|
|
280
|
+
NULL,
|
|
281
|
+
hInstance,
|
|
282
|
+
tooltipData.get());
|
|
283
|
+
|
|
284
|
+
DWM_WINDOW_CORNER_PREFERENCE preference = DWMWCP_ROUNDSMALL;
|
|
285
|
+
UINT borderThickness = 0;
|
|
286
|
+
DwmSetWindowAttribute(m_hwndTip, DWMWA_WINDOW_CORNER_PREFERENCE, &preference, sizeof(preference));
|
|
287
|
+
|
|
288
|
+
tooltipData.release();
|
|
289
|
+
AnimateWindow(m_hwndTip, toolTipAnimationTimeMs, AW_BLEND);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
void TooltipTracker::DestroyTooltip() noexcept {
|
|
294
|
+
if (m_hwndTip) {
|
|
295
|
+
AnimateWindow(m_hwndTip, toolTipAnimationTimeMs, AW_BLEND | AW_HIDE);
|
|
296
|
+
DestroyWindow(m_hwndTip);
|
|
297
|
+
m_hwndTip = nullptr;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
void TooltipTracker::DestroyTimer() noexcept {
|
|
302
|
+
if (m_timer) {
|
|
303
|
+
m_timer.Stop();
|
|
304
|
+
m_timer = nullptr;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
TooltipService::TooltipService(const winrt::Microsoft::ReactNative::ReactPropertyBag &properties)
|
|
309
|
+
: m_properties(properties) {}
|
|
310
|
+
|
|
311
|
+
void TooltipService::StartTracking(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
|
|
312
|
+
m_trackers.push_back(std::make_shared<TooltipTracker>(view, m_properties, this));
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
void TooltipService::StopTracking(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
|
|
316
|
+
for (auto it = m_trackers.begin(); it != m_trackers.end();) {
|
|
317
|
+
if ((*it)->Tag() == view.Tag())
|
|
318
|
+
it = m_trackers.erase(it);
|
|
319
|
+
else
|
|
320
|
+
++it;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
static const ReactPropertyId<winrt::Microsoft::ReactNative::ReactNonAbiValue<std::shared_ptr<TooltipService>>>
|
|
325
|
+
&TooltipServicePropertyId() noexcept {
|
|
326
|
+
static const ReactPropertyId<winrt::Microsoft::ReactNative::ReactNonAbiValue<std::shared_ptr<TooltipService>>> prop{
|
|
327
|
+
L"ReactNative", L"TooltipService"};
|
|
328
|
+
return prop;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
std::shared_ptr<TooltipService> TooltipService::GetCurrent(
|
|
332
|
+
const winrt::Microsoft::ReactNative::ReactPropertyBag &properties) noexcept {
|
|
333
|
+
return *properties.GetOrCreate(TooltipServicePropertyId(), [properties]() -> std::shared_ptr<TooltipService> {
|
|
334
|
+
return std::make_shared<TooltipService>(properties);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
} // namespace winrt::Microsoft::ReactNative
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
|
|
2
|
+
// Copyright (c) Microsoft Corporation.
|
|
3
|
+
// Licensed under the MIT License.
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
#include <Fabric/ReactTaggedView.h>
|
|
8
|
+
#include <winrt/Microsoft.ReactNative.h>
|
|
9
|
+
|
|
10
|
+
namespace winrt::Microsoft::ReactNative {
|
|
11
|
+
|
|
12
|
+
struct TooltipService;
|
|
13
|
+
|
|
14
|
+
struct TooltipTracker {
|
|
15
|
+
TooltipTracker(
|
|
16
|
+
const winrt::Microsoft::ReactNative::ComponentView &view,
|
|
17
|
+
const winrt::Microsoft::ReactNative::ReactPropertyBag &properties,
|
|
18
|
+
TooltipService *outer);
|
|
19
|
+
~TooltipTracker();
|
|
20
|
+
|
|
21
|
+
void OnPointerEntered(
|
|
22
|
+
const winrt::Windows::Foundation::IInspectable &sender,
|
|
23
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept;
|
|
24
|
+
void OnPointerMoved(
|
|
25
|
+
const winrt::Windows::Foundation::IInspectable &sender,
|
|
26
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept;
|
|
27
|
+
void OnPointerExited(
|
|
28
|
+
const winrt::Windows::Foundation::IInspectable &sender,
|
|
29
|
+
const winrt::Microsoft::ReactNative::Composition::Input::PointerRoutedEventArgs &args) noexcept;
|
|
30
|
+
void OnTick(
|
|
31
|
+
const winrt::Windows::Foundation::IInspectable &,
|
|
32
|
+
const winrt::Windows::Foundation::IInspectable &) noexcept;
|
|
33
|
+
void OnUnmounted(
|
|
34
|
+
const winrt::Windows::Foundation::IInspectable &,
|
|
35
|
+
const winrt::Microsoft::ReactNative::ComponentView &) noexcept;
|
|
36
|
+
|
|
37
|
+
facebook::react::Tag Tag() const noexcept;
|
|
38
|
+
|
|
39
|
+
private:
|
|
40
|
+
void ShowTooltip(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
41
|
+
void DestroyTimer() noexcept;
|
|
42
|
+
void DestroyTooltip() noexcept;
|
|
43
|
+
|
|
44
|
+
TooltipService *m_outer;
|
|
45
|
+
winrt::Windows::Foundation::Point m_pos;
|
|
46
|
+
::Microsoft::ReactNative::ReactTaggedView m_view;
|
|
47
|
+
winrt::Microsoft::ReactNative::ITimer m_timer;
|
|
48
|
+
HWND m_hwndTip{nullptr};
|
|
49
|
+
winrt::Microsoft::ReactNative::ReactPropertyBag m_properties;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
struct TooltipService {
|
|
53
|
+
TooltipService(const winrt::Microsoft::ReactNative::ReactPropertyBag &properties);
|
|
54
|
+
void StartTracking(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
55
|
+
void StopTracking(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept;
|
|
56
|
+
|
|
57
|
+
static std::shared_ptr<TooltipService> GetCurrent(
|
|
58
|
+
const winrt::Microsoft::ReactNative::ReactPropertyBag &properties) noexcept;
|
|
59
|
+
|
|
60
|
+
private:
|
|
61
|
+
std::vector<std::shared_ptr<TooltipTracker>> m_enteredTrackers;
|
|
62
|
+
std::vector<std::shared_ptr<TooltipTracker>> m_trackers;
|
|
63
|
+
winrt::Microsoft::ReactNative::ReactPropertyBag m_properties;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
} // namespace winrt::Microsoft::ReactNative
|
|
@@ -206,4 +206,12 @@ void DispatchAccessibilityAction(::Microsoft::ReactNative::ReactTaggedView &view
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
ExpandCollapseState GetExpandCollapseState(const bool &expanded) noexcept {
|
|
210
|
+
if (expanded) {
|
|
211
|
+
return ExpandCollapseState_Expanded;
|
|
212
|
+
} else {
|
|
213
|
+
return ExpandCollapseState_Collapsed;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
209
217
|
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
@@ -35,4 +35,5 @@ std::string extractAccessibilityValue(const facebook::react::AccessibilityValue
|
|
|
35
35
|
|
|
36
36
|
void DispatchAccessibilityAction(::Microsoft::ReactNative::ReactTaggedView &view, const std::string &action) noexcept;
|
|
37
37
|
|
|
38
|
+
ExpandCollapseState GetExpandCollapseState(const bool &expanded) noexcept;
|
|
38
39
|
} // namespace winrt::Microsoft::ReactNative::implementation
|
|
@@ -164,6 +164,9 @@ void FabricUIManager::startSurface(
|
|
|
164
164
|
|
|
165
165
|
void FabricUIManager::stopSurface(facebook::react::SurfaceId surfaceId) noexcept {
|
|
166
166
|
m_surfaceManager->stopSurface(surfaceId);
|
|
167
|
+
auto &rootDescriptor = m_registry.componentViewDescriptorWithTag(surfaceId);
|
|
168
|
+
m_registry.enqueueComponentViewWithComponentHandle(
|
|
169
|
+
facebook::react::RootShadowNode::Handle(), surfaceId, rootDescriptor);
|
|
167
170
|
}
|
|
168
171
|
|
|
169
172
|
winrt::Microsoft::ReactNative::ReactNativeIsland FabricUIManager::GetReactNativeIsland(
|
|
@@ -27,6 +27,10 @@ HostPlatformViewProps::HostPlatformViewProps(
|
|
|
27
27
|
CoreFeatures::enablePropIteratorSetter
|
|
28
28
|
? sourceProps.focusable
|
|
29
29
|
: convertRawProp(context, rawProps, "focusable", sourceProps.focusable, {})),
|
|
30
|
+
tooltip(
|
|
31
|
+
CoreFeatures::enablePropIteratorSetter
|
|
32
|
+
? sourceProps.tooltip
|
|
33
|
+
: convertRawProp(context, rawProps, "tooltip", sourceProps.tooltip, {})),
|
|
30
34
|
accessibilityPosInSet(
|
|
31
35
|
CoreFeatures::enablePropIteratorSetter
|
|
32
36
|
? sourceProps.accessibilityPosInSet
|
|
@@ -82,6 +86,7 @@ void HostPlatformViewProps::setProp(
|
|
|
82
86
|
RAW_SET_PROP_SWITCH_CASE_BASIC(accessibilityLiveRegion);
|
|
83
87
|
RAW_SET_PROP_SWITCH_CASE_BASIC(keyDownEvents);
|
|
84
88
|
RAW_SET_PROP_SWITCH_CASE_BASIC(keyUpEvents);
|
|
89
|
+
RAW_SET_PROP_SWITCH_CASE_BASIC(tooltip);
|
|
85
90
|
}
|
|
86
91
|
}
|
|
87
92
|
|
package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h
CHANGED
|
@@ -29,7 +29,7 @@ class HostPlatformViewProps : public BaseViewProps {
|
|
|
29
29
|
std::string accessibilityLiveRegion{"none"};
|
|
30
30
|
|
|
31
31
|
// std::optional<std::string> overflowAnchor{};
|
|
32
|
-
|
|
32
|
+
std::optional<std::string> tooltip{};
|
|
33
33
|
std::vector<HandledKeyEvent> keyDownEvents{};
|
|
34
34
|
std::vector<HandledKeyEvent> keyUpEvents{};
|
|
35
35
|
};
|
|
@@ -13,7 +13,7 @@ inline bool formsStackingContext(ViewProps const &viewProps) {
|
|
|
13
13
|
// Only Views which are marked as focusable can actually trigger the events, which will already avoid being collapsed.
|
|
14
14
|
constexpr decltype(WindowsViewEvents::bits) focusEventsMask = {
|
|
15
15
|
(1 << (int)WindowsViewEvents::Offset::Focus) & (1 << (int)WindowsViewEvents::Offset::Blur)};
|
|
16
|
-
return (viewProps.windowsEvents.bits & focusEventsMask).any();
|
|
16
|
+
return (viewProps.windowsEvents.bits & focusEventsMask).any() || viewProps.tooltip;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
inline bool formsView(ViewProps const &viewProps) {
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
|
143
143
|
</ClCompile>
|
|
144
144
|
<Link>
|
|
145
|
-
<AdditionalDependencies>winsqlite3.lib;ChakraRT.lib;dxguid.lib;dloadhelper.lib;OneCoreUap_apiset.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
145
|
+
<AdditionalDependencies>winsqlite3.lib;ChakraRT.lib;dxguid.lib;dloadhelper.lib;OneCoreUap_apiset.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
146
146
|
<DelayLoadDLLs>
|
|
147
147
|
api-ms-win-core-file-l1-2-0.dll;
|
|
148
148
|
api-ms-win-core-windowserrorreporting-l1-1-0.dll;
|
|
@@ -53,7 +53,6 @@ struct ReactCoreInjection : ReactCoreInjectionT<ReactCoreInjection> {
|
|
|
53
53
|
static uint64_t GetTopLevelWindowId(const IReactPropertyBag &properties) noexcept;
|
|
54
54
|
static void SetTopLevelWindowId(const IReactPropertyBag &properties, uint64_t windowId) noexcept;
|
|
55
55
|
|
|
56
|
-
static ITimer CreateTimer(const IReactPropertyBag &properties);
|
|
57
56
|
static TimerFactory GetTimerFactory(const IReactPropertyBag &properties) noexcept;
|
|
58
57
|
static void SetTimerFactory(const IReactPropertyBag &properties, const TimerFactory &timerFactory) noexcept;
|
|
59
58
|
};
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.75.
|
|
13
|
+
<ReactNativeWindowsVersion>0.75.7</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>75</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>7</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
18
|
+
<ReactNativeWindowsCommitId>b4bb6c6d999fceeaf2316b86283310e8f6dbca28</ReactNativeWindowsCommitId>
|
|
19
19
|
</PropertyGroup>
|
|
20
20
|
</Project>
|
package/Shared/Shared.vcxitems
CHANGED
|
@@ -150,6 +150,9 @@
|
|
|
150
150
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\TextDrawing.cpp">
|
|
151
151
|
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
152
152
|
</ClCompile>
|
|
153
|
+
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\TooltipService.cpp">
|
|
154
|
+
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
155
|
+
</ClCompile>
|
|
153
156
|
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\UiaHelpers.cpp">
|
|
154
157
|
<ExcludedFromBuild Condition="'$(UseFabric)' != 'true'">true</ExcludedFromBuild>
|
|
155
158
|
</ClCompile>
|
|
@@ -329,6 +329,8 @@
|
|
|
329
329
|
<ClCompile Include="$(ReactNativeDir)\ReactCommon\cxxreact\JSExecutor.cpp" />
|
|
330
330
|
<ClCompile Include="$(ReactNativeDir)\ReactCommon\jsinspector-modern\RuntimeTargetConsole.cpp" />
|
|
331
331
|
<ClCompile Include="$(MSBuildThisFileDirectory)Networking\NetworkPropertyIds.cpp" />
|
|
332
|
+
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\AbiEventEmitter.cpp" />
|
|
333
|
+
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Fabric\Composition\TooltipService.cpp" />
|
|
332
334
|
</ItemGroup>
|
|
333
335
|
<ItemGroup>
|
|
334
336
|
<Filter Include="Source Files">
|
package/just-task.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-windows",
|
|
3
|
-
"version": "0.75.
|
|
3
|
+
"version": "0.75.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@react-native-community/cli": "14.1.0",
|
|
27
27
|
"@react-native-community/cli-platform-android": "14.1.0",
|
|
28
28
|
"@react-native-community/cli-platform-ios": "14.1.0",
|
|
29
|
-
"@react-native-windows/cli": "0.75.
|
|
29
|
+
"@react-native-windows/cli": "0.75.5",
|
|
30
30
|
"@react-native/assets": "1.0.0",
|
|
31
31
|
"@react-native/assets-registry": "0.75.3",
|
|
32
32
|
"@react-native/codegen": "0.75.3",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"yargs": "^17.6.2"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@react-native-windows/codegen": "0.75.
|
|
70
|
+
"@react-native-windows/codegen": "0.75.3",
|
|
71
71
|
"@react-native/metro-config": "0.75.3",
|
|
72
72
|
"@rnw-scripts/babel-react-native-config": "0.0.0",
|
|
73
73
|
"@rnw-scripts/eslint-config": "1.2.23",
|
|
@@ -78,7 +78,6 @@
|
|
|
78
78
|
"@types/node": "^18.0.0",
|
|
79
79
|
"@types/react": "^18.2.6",
|
|
80
80
|
"eslint": "^8.19.0",
|
|
81
|
-
"eslint-plugin-prettier": "^4.2.1",
|
|
82
81
|
"flow-bin": "^0.217.2",
|
|
83
82
|
"jscodeshift": "^0.14.0",
|
|
84
83
|
"just-scripts": "^1.3.3",
|
|
@@ -21,7 +21,10 @@ async function preInstall(config = {}, options = {}) {}
|
|
|
21
21
|
|
|
22
22
|
async function getFileMappings(config = {}, options = {}) {
|
|
23
23
|
const projectRoot = config?.root ?? process.cwd();
|
|
24
|
-
const {rnwPath, rnwVersion, devMode, isCanary} = templateUtils.getRnwInfo(
|
|
24
|
+
const {rnwPath, rnwVersion, devMode, isCanary} = templateUtils.getRnwInfo(
|
|
25
|
+
config,
|
|
26
|
+
options,
|
|
27
|
+
);
|
|
25
28
|
|
|
26
29
|
const projectName =
|
|
27
30
|
config?.project?.windows?.project?.projectName ?? options?.name ?? 'MyApp';
|
|
@@ -49,7 +52,9 @@ async function getFileMappings(config = {}, options = {}) {
|
|
|
49
52
|
namespaceCpp: namespaceCpp,
|
|
50
53
|
|
|
51
54
|
rnwVersion: rnwVersion,
|
|
52
|
-
rnwPathFromProjectRoot: path
|
|
55
|
+
rnwPathFromProjectRoot: path
|
|
56
|
+
.relative(projectRoot, rnwPath)
|
|
57
|
+
.replace(/\//g, '\\'),
|
|
53
58
|
|
|
54
59
|
mainComponentName,
|
|
55
60
|
|
|
@@ -67,7 +72,7 @@ async function getFileMappings(config = {}, options = {}) {
|
|
|
67
72
|
devMode,
|
|
68
73
|
|
|
69
74
|
useNuGets: !devMode, // default is to use published NuGets except in devMode, change to true here if you want to test devMode and nugets simultaneously
|
|
70
|
-
addReactNativePublicAdoFeed: isCanary,
|
|
75
|
+
addReactNativePublicAdoFeed: true || isCanary, // Temporary true for all new projects until code-signing is restored, see issue #14030
|
|
71
76
|
|
|
72
77
|
cppNugetPackages,
|
|
73
78
|
};
|
|
@@ -76,7 +76,10 @@ async function getFileMappings(config = {}, options = {}) {
|
|
|
76
76
|
);
|
|
77
77
|
|
|
78
78
|
const projectRoot = libConfig.root ?? process.cwd();
|
|
79
|
-
const {rnwPath, rnwVersion, devMode, isCanary} = templateUtils.getRnwInfo(
|
|
79
|
+
const {rnwPath, rnwVersion, devMode, isCanary} = templateUtils.getRnwInfo(
|
|
80
|
+
libConfig,
|
|
81
|
+
libOptions,
|
|
82
|
+
);
|
|
80
83
|
|
|
81
84
|
const projectName =
|
|
82
85
|
libConfig?.project?.windows?.projects[0]?.projectName ??
|
|
@@ -102,7 +105,9 @@ async function getFileMappings(config = {}, options = {}) {
|
|
|
102
105
|
namespaceCpp: namespaceCpp,
|
|
103
106
|
|
|
104
107
|
rnwVersion: rnwVersion,
|
|
105
|
-
rnwPathFromProjectRoot: path
|
|
108
|
+
rnwPathFromProjectRoot: path
|
|
109
|
+
.relative(projectRoot, rnwPath)
|
|
110
|
+
.replace(/\//g, '\\'),
|
|
106
111
|
|
|
107
112
|
// Visual Studio is very picky about the casing of the guids for projects, project references and the solution
|
|
108
113
|
// https://www.bing.com/search?q=visual+studio+project+guid+casing&cvid=311a5ad7f9fc41089507b24600d23ee7&FORM=ANAB01&PC=U531
|
|
@@ -115,7 +120,7 @@ async function getFileMappings(config = {}, options = {}) {
|
|
|
115
120
|
devMode,
|
|
116
121
|
|
|
117
122
|
useNuGets: !devMode, // default is to use published NuGets except in devMode, change to true here if you want to test devMode and nugets simultaneously
|
|
118
|
-
addReactNativePublicAdoFeed: isCanary,
|
|
123
|
+
addReactNativePublicAdoFeed: true || isCanary, // Temporary true for all new projects until code-signing is restored, see issue #14030
|
|
119
124
|
|
|
120
125
|
cppNugetPackages,
|
|
121
126
|
};
|
|
@@ -112,9 +112,8 @@ async function runNpmInstall(config = {}, options = {}) {
|
|
|
112
112
|
|
|
113
113
|
async function updateProjectPackageJson(config = {}, options = {}, props = {}) {
|
|
114
114
|
const projectRoot = config?.root ?? process.cwd();
|
|
115
|
-
const projectPackage =
|
|
116
|
-
projectRoot
|
|
117
|
-
);
|
|
115
|
+
const projectPackage =
|
|
116
|
+
await pkgUtils.WritableNpmPackage.fromPath(projectRoot);
|
|
118
117
|
|
|
119
118
|
if (!projectPackage) {
|
|
120
119
|
throw new Error(
|