react-native-windows 0.0.0-canary.476 → 0.0.0-canary.477
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/.flowconfig +1 -1
- package/Libraries/ActionSheetIOS/ActionSheetIOS.js +7 -0
- package/Libraries/ActionSheetIOS/NativeActionSheetManager.js +1 -0
- package/Libraries/Blob/URL.js +7 -1
- package/Libraries/Components/StatusBar/StatusBar.js +6 -1
- package/Libraries/Components/TextInput/TextInputState.js +10 -2
- package/Libraries/Components/TextInput/TextInputState.windows.js +10 -3
- package/Libraries/Components/TextInput/WindowsTextInputNativeComponent.js +1 -1
- package/Libraries/Core/ExceptionsManager.js +1 -1
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/LogBox/Data/LogBoxData.js +1 -1
- package/Libraries/LogBox/Data/LogBoxLog.js +1 -1
- package/Libraries/LogBox/Data/LogBoxSymbolication.js +1 -1
- package/Libraries/LogBox/Data/parseLogBoxLog.js +1 -1
- package/Libraries/LogBox/LogBox.js +2 -21
- package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +1 -0
- package/Microsoft.ReactNative/Fabric/ComponentViewRegistry.cpp +13 -0
- package/Microsoft.ReactNative/Fabric/ComponentViewRegistry.h +1 -0
- package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +11 -14
- package/Microsoft.ReactNative/Fabric/ScrollViewComponentView.cpp +2 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentDescriptor.h +197 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentView.cpp +308 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputComponentView.h +52 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputEventEmitter.cpp +31 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputEventEmitter.h +33 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputProps.cpp +81 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputProps.h +132 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputShadowNode.cpp +193 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputShadowNode.h +85 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputState.cpp +76 -0
- package/Microsoft.ReactNative/Fabric/TextInput/WindowsTextInputState.h +99 -0
- package/Microsoft.ReactNative/Fabric/ViewComponentView.cpp +31 -3
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/slider/SliderMeasurementsManager.cpp +26 -15
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +60 -49
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.h +11 -3
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +5 -0
- package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +14 -1
- package/Microsoft.ReactNative/Views/TextInputViewManager.cpp +1 -1
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems +5 -1
- package/Microsoft.ReactNative.Cxx/Microsoft.ReactNative.Cxx.vcxitems.filters +2 -3
- package/Microsoft.ReactNative.Managed/packages.lock.json +1 -1
- package/PropertySheets/Generated/PackageVersion.g.props +1 -1
- package/PropertySheets/React.Cpp.props +1 -0
- package/ReactCommon/ReactCommon.vcxproj +2 -1
- package/ReactCommon/ReactCommon.vcxproj.filters +4 -1
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/CallbackWrapper.h +103 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModuleUtils.h +61 -0
- package/Scripts/OfficeReact.Win32.nuspec +0 -2
- package/Scripts/Tfs/Layout-MSRN-Headers.ps1 +2 -1
- package/Shared/DevSupportManager.cpp +7 -2
- package/Shared/OInstance.cpp +1 -1
- package/codegen/NativeActionSheetManagerSpec.g.h +6 -0
- package/jest/preprocessor.js +24 -106
- package/jest/preprocessor_DO_NOT_USE.js +122 -0
- package/package.json +8 -8
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/RawPropsParser.cpp +0 -162
- package/include/Shared/ViewManager.h +0 -34
package/.flowconfig
CHANGED
|
@@ -143,6 +143,13 @@ const ActionSheetIOS = {
|
|
|
143
143
|
successCallback,
|
|
144
144
|
);
|
|
145
145
|
},
|
|
146
|
+
|
|
147
|
+
dismissActionSheet: () => {
|
|
148
|
+
invariant(RCTActionSheetManager, "ActionSheetManager doesn't exist");
|
|
149
|
+
if (typeof RCTActionSheetManager.dismissActionSheet === 'function') {
|
|
150
|
+
RCTActionSheetManager.dismissActionSheet();
|
|
151
|
+
}
|
|
152
|
+
},
|
|
146
153
|
};
|
|
147
154
|
|
|
148
155
|
module.exports = ActionSheetIOS;
|
|
@@ -47,6 +47,7 @@ export interface Spec extends TurboModule {
|
|
|
47
47
|
|}) => void,
|
|
48
48
|
successCallback: (completed: boolean, activityType: ?string) => void,
|
|
49
49
|
) => void;
|
|
50
|
+
+dismissActionSheet?: () => void;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
export default (TurboModuleRegistry.get<Spec>('ActionSheetManager'): ?Spec);
|
package/Libraries/Blob/URL.js
CHANGED
|
@@ -101,7 +101,13 @@ export class URLSearchParams {
|
|
|
101
101
|
}
|
|
102
102
|
const last = this._searchParams.length - 1;
|
|
103
103
|
return this._searchParams.reduce((acc, curr, index) => {
|
|
104
|
-
return
|
|
104
|
+
return (
|
|
105
|
+
acc +
|
|
106
|
+
encodeURIComponent(curr[0]) +
|
|
107
|
+
'=' +
|
|
108
|
+
encodeURIComponent(curr[1]) +
|
|
109
|
+
(index === last ? '' : '&')
|
|
110
|
+
);
|
|
105
111
|
}, '');
|
|
106
112
|
}
|
|
107
113
|
}
|
|
@@ -471,7 +471,12 @@ class StatusBar extends React.Component<Props> {
|
|
|
471
471
|
if (!oldProps || oldProps.hidden.value !== mergedProps.hidden.value) {
|
|
472
472
|
NativeStatusBarManagerAndroid.setHidden(mergedProps.hidden.value);
|
|
473
473
|
}
|
|
474
|
-
|
|
474
|
+
// Activities are not translucent by default, so always set if true.
|
|
475
|
+
if (
|
|
476
|
+
!oldProps ||
|
|
477
|
+
oldProps.translucent !== mergedProps.translucent ||
|
|
478
|
+
mergedProps.translucent
|
|
479
|
+
) {
|
|
475
480
|
NativeStatusBarManagerAndroid.setTranslucent(mergedProps.translucent);
|
|
476
481
|
}
|
|
477
482
|
}
|
|
@@ -73,7 +73,7 @@ function blurField(textFieldID: ?number) {
|
|
|
73
73
|
/**
|
|
74
74
|
* @param {number} TextInputID id of the text field to focus
|
|
75
75
|
* Focuses the specified text field
|
|
76
|
-
* noop if the text field was already focused
|
|
76
|
+
* noop if the text field was already focused or if the field is not editable
|
|
77
77
|
*/
|
|
78
78
|
function focusTextInput(textField: ?ComponentRef) {
|
|
79
79
|
if (typeof textField === 'number') {
|
|
@@ -86,7 +86,15 @@ function focusTextInput(textField: ?ComponentRef) {
|
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
if (
|
|
89
|
+
if (textField != null) {
|
|
90
|
+
const fieldCanBeFocused =
|
|
91
|
+
currentlyFocusedInputRef !== textField &&
|
|
92
|
+
// $FlowFixMe - `currentProps` is missing in `NativeMethods`
|
|
93
|
+
textField.currentProps?.editable !== false;
|
|
94
|
+
|
|
95
|
+
if (!fieldCanBeFocused) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
90
98
|
focusInput(textField);
|
|
91
99
|
if (Platform.OS === 'ios') {
|
|
92
100
|
// This isn't necessarily a single line text input
|
|
@@ -20,7 +20,6 @@ import {Commands as iOSTextInputCommands} from '../../Components/TextInput/RCTSi
|
|
|
20
20
|
import {Commands as WindowsTextInputCommands} from '../../Components/TextInput/WindowsTextInputNativeComponent';
|
|
21
21
|
|
|
22
22
|
import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
|
|
23
|
-
import {UIManager} from 'react-native';
|
|
24
23
|
type ComponentRef = React.ElementRef<HostComponent<mixed>>;
|
|
25
24
|
|
|
26
25
|
let currentlyFocusedInputRef: ?ComponentRef = null;
|
|
@@ -75,7 +74,7 @@ function blurField(textFieldID: ?number) {
|
|
|
75
74
|
/**
|
|
76
75
|
* @param {number} TextInputID id of the text field to focus
|
|
77
76
|
* Focuses the specified text field
|
|
78
|
-
* noop if the text field was already focused
|
|
77
|
+
* noop if the text field was already focused or if the field is not editable
|
|
79
78
|
*/
|
|
80
79
|
function focusTextInput(textField: ?ComponentRef) {
|
|
81
80
|
if (typeof textField === 'number') {
|
|
@@ -97,7 +96,15 @@ function focusTextInput(textField: ?ComponentRef) {
|
|
|
97
96
|
focusInput(textField);
|
|
98
97
|
WindowsTextInputCommands.focus(textField);
|
|
99
98
|
// Windows]
|
|
100
|
-
} else if (
|
|
99
|
+
} else if (textField != null) {
|
|
100
|
+
const fieldCanBeFocused =
|
|
101
|
+
currentlyFocusedInputRef !== textField &&
|
|
102
|
+
// $FlowFixMe - `currentProps` is missing in `NativeMethods`
|
|
103
|
+
textField.currentProps?.editable !== false;
|
|
104
|
+
|
|
105
|
+
if (!fieldCanBeFocused) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
101
108
|
focusInput(textField);
|
|
102
109
|
if (Platform.OS === 'ios') {
|
|
103
110
|
// This isn't necessarily a single line text input
|
|
@@ -17,7 +17,7 @@ export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
|
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
const WindowsTextInputComponent: NativeType =
|
|
20
|
-
requireNativeComponent<mixed>('
|
|
20
|
+
requireNativeComponent<mixed>('WindowsTextInput');
|
|
21
21
|
|
|
22
22
|
export default WindowsTextInputComponent;
|
|
23
23
|
// [Windows]
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @flow
|
|
7
|
+
* @flow strict
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -75,24 +75,6 @@ if (__DEV__) {
|
|
|
75
75
|
consoleErrorImpl = registerError;
|
|
76
76
|
consoleWarnImpl = registerWarning;
|
|
77
77
|
|
|
78
|
-
if ((console: any).disableYellowBox === true) {
|
|
79
|
-
LogBoxData.setDisabled(true);
|
|
80
|
-
console.warn(
|
|
81
|
-
'console.disableYellowBox has been deprecated and will be removed in a future release. Please use LogBox.ignoreAllLogs(value) instead.',
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
(Object.defineProperty: any)(console, 'disableYellowBox', {
|
|
86
|
-
configurable: true,
|
|
87
|
-
get: () => LogBoxData.isDisabled(),
|
|
88
|
-
set: value => {
|
|
89
|
-
LogBoxData.setDisabled(value);
|
|
90
|
-
console.warn(
|
|
91
|
-
'console.disableYellowBox has been deprecated and will be removed in a future release. Please use LogBox.ignoreAllLogs(value) instead.',
|
|
92
|
-
);
|
|
93
|
-
},
|
|
94
|
-
});
|
|
95
|
-
|
|
96
78
|
if (Platform.isTesting) {
|
|
97
79
|
LogBoxData.setDisabled(true);
|
|
98
80
|
}
|
|
@@ -115,7 +97,6 @@ if (__DEV__) {
|
|
|
115
97
|
// After uninstalling: original > LogBox (noop) > OtherErrorHandler
|
|
116
98
|
consoleErrorImpl = originalConsoleError;
|
|
117
99
|
consoleWarnImpl = originalConsoleWarn;
|
|
118
|
-
delete (console: any).disableLogBox;
|
|
119
100
|
},
|
|
120
101
|
|
|
121
102
|
isInstalled(): boolean {
|
|
@@ -153,7 +134,7 @@ if (__DEV__) {
|
|
|
153
134
|
return typeof args[0] === 'string' && args[0].startsWith('(ADVICE)');
|
|
154
135
|
};
|
|
155
136
|
|
|
156
|
-
const isWarningModuleWarning = (...args:
|
|
137
|
+
const isWarningModuleWarning = (...args: Array<mixed>) => {
|
|
157
138
|
return typeof args[0] === 'string' && args[0].startsWith('Warning: ');
|
|
158
139
|
};
|
|
159
140
|
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
#include <react/renderer/components/text/TextShadowNode.h>
|
|
20
20
|
#include <react/renderer/components/textinput/iostextinput/TextInputShadowNode.h>
|
|
21
21
|
#include <react/renderer/components/view/ViewShadowNode.h>
|
|
22
|
+
#include "TextInput/WindowsTextInputShadowNode.h"
|
|
22
23
|
|
|
23
24
|
#include "ActivityIndicatorComponentView.h"
|
|
24
25
|
#include "ImageComponentView.h"
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
#include "SliderComponentView.h"
|
|
28
29
|
#include "SwitchComponentView.h"
|
|
29
30
|
#include "TextComponentView.h"
|
|
31
|
+
#include "TextInput/WindowsTextInputComponentView.h"
|
|
30
32
|
#include "ViewComponentView.h"
|
|
31
33
|
#include "XamlView.h"
|
|
32
34
|
|
|
@@ -55,6 +57,8 @@ ComponentViewDescriptor const &ComponentViewRegistry::dequeueComponentViewWithCo
|
|
|
55
57
|
view = std::make_shared<SliderComponentView>(m_context);
|
|
56
58
|
} else if (componentHandle == facebook::react::SwitchShadowNode::Handle()) {
|
|
57
59
|
view = std::make_shared<SwitchComponentView>(m_context);
|
|
60
|
+
} else if (componentHandle == facebook::react::WindowsTextInputShadowNode::Handle()) {
|
|
61
|
+
view = std::make_shared<WindowsTextInputComponentView>();
|
|
58
62
|
} else if (componentHandle == facebook::react::ActivityIndicatorViewShadowNode::Handle()) {
|
|
59
63
|
view = std::make_shared<ActivityIndicatorComponentView>();
|
|
60
64
|
} else {
|
|
@@ -80,6 +84,15 @@ ComponentViewDescriptor const &ComponentViewRegistry::componentViewDescriptorWit
|
|
|
80
84
|
return iterator->second;
|
|
81
85
|
}
|
|
82
86
|
|
|
87
|
+
std::shared_ptr<IComponentView> ComponentViewRegistry::findComponentViewWithTag(
|
|
88
|
+
facebook::react::Tag tag) const noexcept {
|
|
89
|
+
auto iterator = m_registry.find(tag);
|
|
90
|
+
if (iterator == m_registry.end()) {
|
|
91
|
+
return nullptr;
|
|
92
|
+
}
|
|
93
|
+
return iterator->second.view;
|
|
94
|
+
}
|
|
95
|
+
|
|
83
96
|
void ComponentViewRegistry::enqueueComponentViewWithComponentHandle(
|
|
84
97
|
facebook::react::ComponentHandle componentHandle,
|
|
85
98
|
facebook::react::Tag tag,
|
|
@@ -23,6 +23,7 @@ class ComponentViewRegistry final {
|
|
|
23
23
|
facebook::react::ComponentHandle componentHandle,
|
|
24
24
|
facebook::react::Tag tag) noexcept;
|
|
25
25
|
ComponentViewDescriptor const &componentViewDescriptorWithTag(facebook::react::Tag tag) const noexcept;
|
|
26
|
+
std::shared_ptr<IComponentView> findComponentViewWithTag(facebook::react::Tag tag) const noexcept;
|
|
26
27
|
void enqueueComponentViewWithComponentHandle(
|
|
27
28
|
facebook::react::ComponentHandle componentHandle,
|
|
28
29
|
facebook::react::Tag tag,
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
#include <react/utils/ContextContainer.h>
|
|
30
30
|
#include <runtimeexecutor/ReactCommon/RuntimeExecutor.h>
|
|
31
31
|
#include <winrt/Windows.Graphics.Display.h>
|
|
32
|
+
#include "TextInput/WindowsTextInputComponentDescriptor.h"
|
|
32
33
|
#include "Unicode.h"
|
|
33
34
|
|
|
34
35
|
#pragma warning(push)
|
|
@@ -153,6 +154,8 @@ std::shared_ptr<facebook::react::ComponentDescriptorProviderRegistry const> shar
|
|
|
153
154
|
facebook::react::concreteComponentDescriptorProvider<facebook::react::TextInputComponentDescriptor>());
|
|
154
155
|
providerRegistry->add(
|
|
155
156
|
facebook::react::concreteComponentDescriptorProvider<facebook::react::ViewComponentDescriptor>());
|
|
157
|
+
providerRegistry->add(
|
|
158
|
+
facebook::react::concreteComponentDescriptorProvider<facebook::react::WindowsTextInputComponentDescriptor>());
|
|
156
159
|
return providerRegistry;
|
|
157
160
|
}();
|
|
158
161
|
|
|
@@ -166,6 +169,10 @@ void FabricUIManager::installFabricUIManager() noexcept {
|
|
|
166
169
|
std::lock_guard<std::mutex> schedulerLock(m_schedulerMutex);
|
|
167
170
|
|
|
168
171
|
facebook::react::ContextContainer::Shared contextContainer = std::make_shared<facebook::react::ContextContainer>();
|
|
172
|
+
|
|
173
|
+
// This allows access to our ReactContext from the contextContainer thats passed around the fabric codebase
|
|
174
|
+
contextContainer->insert("MSRN.ReactContext", m_context);
|
|
175
|
+
|
|
169
176
|
auto runtimeExecutor = SchedulerSettings::GetRuntimeExecutor(m_context.Properties());
|
|
170
177
|
|
|
171
178
|
// TODO: T31905686 Create synchronous Event Beat
|
|
@@ -205,9 +212,6 @@ void FabricUIManager::installFabricUIManager() noexcept {
|
|
|
205
212
|
toolbox.runtimeExecutor = runtimeExecutor;
|
|
206
213
|
toolbox.synchronousEventBeatFactory = synchronousBeatFactory;
|
|
207
214
|
toolbox.asynchronousEventBeatFactory = asynchronousBeatFactory;
|
|
208
|
-
// We currently rely on using XAML elements to perform measure/layout,
|
|
209
|
-
// which requires that the background thread also be the UI thread
|
|
210
|
-
/*
|
|
211
215
|
toolbox.backgroundExecutor = [context = m_context,
|
|
212
216
|
dispatcher = Mso::DispatchQueue::MakeLooperQueue()](std::function<void()> &&callback) {
|
|
213
217
|
if (context.UIDispatcher().HasThreadAccess()) {
|
|
@@ -217,15 +221,6 @@ void FabricUIManager::installFabricUIManager() noexcept {
|
|
|
217
221
|
|
|
218
222
|
dispatcher.Post(std::move(callback));
|
|
219
223
|
};
|
|
220
|
-
*/
|
|
221
|
-
toolbox.backgroundExecutor = [context = m_context](std::function<void()> &&callback) {
|
|
222
|
-
if (context.UIDispatcher().HasThreadAccess()) {
|
|
223
|
-
callback();
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
context.UIDispatcher().Post(std::move(callback));
|
|
228
|
-
};
|
|
229
224
|
|
|
230
225
|
m_scheduler = std::make_shared<facebook::react::Scheduler>(
|
|
231
226
|
toolbox, (/*animationDriver_ ? animationDriver_.get() :*/ nullptr), this);
|
|
@@ -501,8 +496,10 @@ void FabricUIManager::schedulerDidDispatchCommand(
|
|
|
501
496
|
m_context.UIDispatcher().Post(
|
|
502
497
|
[wkThis = weak_from_this(), commandName, tag = shadowView.tag, args = folly::dynamic(arg)]() {
|
|
503
498
|
if (auto pThis = wkThis.lock()) {
|
|
504
|
-
auto
|
|
505
|
-
|
|
499
|
+
auto view = pThis->m_registry.findComponentViewWithTag(tag);
|
|
500
|
+
if (view) {
|
|
501
|
+
view->handleCommand(commandName, args);
|
|
502
|
+
}
|
|
506
503
|
}
|
|
507
504
|
});
|
|
508
505
|
}
|
|
@@ -23,6 +23,8 @@ ScrollViewComponentView::ScrollViewComponentView() {
|
|
|
23
23
|
// m_props = defaultProps;
|
|
24
24
|
|
|
25
25
|
m_element.Content(m_contentPanel);
|
|
26
|
+
m_contentPanel.VerticalAlignment(xaml::VerticalAlignment::Top);
|
|
27
|
+
m_contentPanel.HorizontalAlignment(xaml::HorizontalAlignment::Left);
|
|
26
28
|
|
|
27
29
|
m_scrollViewerViewChangingRevoker =
|
|
28
30
|
m_element.ViewChanging(winrt::auto_revoke, [this](const auto &sender, const auto &args) {
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "WindowsTextInputShadowNode.h"
|
|
7
|
+
|
|
8
|
+
#include <yoga/CompactValue.h>
|
|
9
|
+
#include <yoga/YGEnums.h>
|
|
10
|
+
#include <yoga/YGValue.h>
|
|
11
|
+
|
|
12
|
+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
13
|
+
|
|
14
|
+
namespace facebook {
|
|
15
|
+
namespace react {
|
|
16
|
+
|
|
17
|
+
// [Windows
|
|
18
|
+
void InitTextInputThemeInfo(const Mso::React::IReactContext &reactContext) {
|
|
19
|
+
xaml::Thickness textBoxPadding;
|
|
20
|
+
xaml::Application::Current().Resources().TryLookup(winrt::box_value(L"TextControlThemePadding")).as(textBoxPadding);
|
|
21
|
+
winrt::Microsoft::ReactNative::ReactPropertyBag(reactContext.Properties())
|
|
22
|
+
.Set(winrt::Microsoft::ReactNative::ReactPropertyId<xaml::Thickness>(L"TextBoxDefaultPadding"), textBoxPadding);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
YGStyle::Edges PaddingFromContext(const facebook::react::ContextContainer &contextContainer) {
|
|
26
|
+
auto context = contextContainer.at<winrt::Microsoft::ReactNative::ReactContext>("MSRN.ReactContext");
|
|
27
|
+
auto defaultPadding = *context.Properties().Get(
|
|
28
|
+
winrt::Microsoft::ReactNative::ReactPropertyId<xaml::Thickness>(L"TextBoxDefaultPadding"));
|
|
29
|
+
YGStyle::Edges theme;
|
|
30
|
+
theme[YGEdgeStart] = YGValue{static_cast<float>(defaultPadding.Left), YGUnitPoint};
|
|
31
|
+
theme[YGEdgeEnd] = YGValue{static_cast<float>(defaultPadding.Right), YGUnitPoint};
|
|
32
|
+
theme[YGEdgeTop] = YGValue{static_cast<float>(defaultPadding.Top), YGUnitPoint};
|
|
33
|
+
theme[YGEdgeBottom] = YGValue{static_cast<float>(defaultPadding.Bottom), YGUnitPoint};
|
|
34
|
+
return theme;
|
|
35
|
+
}
|
|
36
|
+
// Windows]
|
|
37
|
+
|
|
38
|
+
/*
|
|
39
|
+
* Descriptor for <WindowsTextInput> component.
|
|
40
|
+
*/
|
|
41
|
+
class WindowsTextInputComponentDescriptor final : public ConcreteComponentDescriptor<WindowsTextInputShadowNode> {
|
|
42
|
+
public:
|
|
43
|
+
WindowsTextInputComponentDescriptor(ComponentDescriptorParameters const ¶meters)
|
|
44
|
+
: ConcreteComponentDescriptor<WindowsTextInputShadowNode>(parameters) {
|
|
45
|
+
// Every single `WindowsTextInputShadowNode` will have a reference to
|
|
46
|
+
// a shared `TextLayoutManager`.
|
|
47
|
+
textLayoutManager_ = std::make_shared<TextLayoutManager>(contextContainer_);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
virtual State::Shared createInitialState(ShadowNodeFragment const &fragment, ShadowNodeFamily::Shared const &family)
|
|
51
|
+
const override {
|
|
52
|
+
/*
|
|
53
|
+
int surfaceId = family->getSurfaceId();
|
|
54
|
+
|
|
55
|
+
YGStyle::Edges theme;
|
|
56
|
+
// TODO: figure out RTL/start/end/left/right stuff here
|
|
57
|
+
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
|
|
58
|
+
surfaceIdToThemePaddingMap_.end()) {
|
|
59
|
+
theme = surfaceIdToThemePaddingMap_[surfaceId];
|
|
60
|
+
} else {
|
|
61
|
+
const jni::global_ref<jobject> &fabricUIManager =
|
|
62
|
+
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
|
|
63
|
+
|
|
64
|
+
auto env = jni::Environment::current();
|
|
65
|
+
auto defaultTextInputPaddingArray = env->NewFloatArray(4);
|
|
66
|
+
static auto getThemeData =
|
|
67
|
+
jni::findClassStatic(UIManagerJavaDescriptor)
|
|
68
|
+
->getMethod<jboolean(jint, jfloatArray)>("getThemeData");
|
|
69
|
+
|
|
70
|
+
if (getThemeData(
|
|
71
|
+
fabricUIManager, surfaceId, defaultTextInputPaddingArray)) {
|
|
72
|
+
jfloat *defaultTextInputPadding =
|
|
73
|
+
env->GetFloatArrayElements(defaultTextInputPaddingArray, 0);
|
|
74
|
+
theme[YGEdgeStart] = (YGValue){defaultTextInputPadding[0], YGUnitPoint};
|
|
75
|
+
theme[YGEdgeEnd] = (YGValue){defaultTextInputPadding[1], YGUnitPoint};
|
|
76
|
+
theme[YGEdgeTop] = (YGValue){defaultTextInputPadding[2], YGUnitPoint};
|
|
77
|
+
theme[YGEdgeBottom] =
|
|
78
|
+
(YGValue){defaultTextInputPadding[3], YGUnitPoint};
|
|
79
|
+
surfaceIdToThemePaddingMap_.emplace(std::make_pair(surfaceId, theme));
|
|
80
|
+
env->ReleaseFloatArrayElements(
|
|
81
|
+
defaultTextInputPaddingArray, defaultTextInputPadding, JNI_ABORT);
|
|
82
|
+
}
|
|
83
|
+
env->DeleteLocalRef(defaultTextInputPaddingArray);
|
|
84
|
+
}
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
auto theme = PaddingFromContext(*contextContainer_); // [Windows]
|
|
88
|
+
|
|
89
|
+
return std::make_shared<WindowsTextInputShadowNode::ConcreteState>(
|
|
90
|
+
std::make_shared<WindowsTextInputState const>(WindowsTextInputState(
|
|
91
|
+
0,
|
|
92
|
+
{},
|
|
93
|
+
{},
|
|
94
|
+
{},
|
|
95
|
+
{},
|
|
96
|
+
{},
|
|
97
|
+
((YGValue)theme[YGEdgeStart]).value,
|
|
98
|
+
((YGValue)theme[YGEdgeEnd]).value,
|
|
99
|
+
((YGValue)theme[YGEdgeTop]).value,
|
|
100
|
+
((YGValue)theme[YGEdgeBottom]).value)),
|
|
101
|
+
family);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
protected:
|
|
105
|
+
void adopt(ShadowNode::Unshared const &shadowNode) const override {
|
|
106
|
+
auto textInputShadowNode = std::static_pointer_cast<WindowsTextInputShadowNode>(shadowNode);
|
|
107
|
+
|
|
108
|
+
// `ParagraphShadowNode` uses `TextLayoutManager` to measure text content
|
|
109
|
+
// and communicate text rendering metrics to mounting layer.
|
|
110
|
+
textInputShadowNode->setTextLayoutManager(textLayoutManager_);
|
|
111
|
+
|
|
112
|
+
textInputShadowNode->setContextContainer(const_cast<ContextContainer *>(getContextContainer().get()));
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
int surfaceId = textInputShadowNode->getSurfaceId();
|
|
116
|
+
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
|
|
117
|
+
surfaceIdToThemePaddingMap_.end()) */
|
|
118
|
+
{
|
|
119
|
+
// YGStyle::Edges theme = surfaceIdToThemePaddingMap_[surfaceId];
|
|
120
|
+
|
|
121
|
+
auto theme = PaddingFromContext(*contextContainer_); // [Windows]
|
|
122
|
+
|
|
123
|
+
// Override padding
|
|
124
|
+
// Node is still unsealed during adoption, before layout is complete
|
|
125
|
+
// TODO: T62959168 account for RTL and paddingLeft when setting default
|
|
126
|
+
// paddingStart, and vice-versa with paddingRight/paddingEnd.
|
|
127
|
+
// For now this assumes no RTL.
|
|
128
|
+
YGStyle::Edges result = textInputShadowNode->getConcreteProps().yogaStyle.padding();
|
|
129
|
+
bool changedPadding = false;
|
|
130
|
+
if (!textInputShadowNode->getConcreteProps().hasPadding &&
|
|
131
|
+
!textInputShadowNode->getConcreteProps().hasPaddingStart &&
|
|
132
|
+
!textInputShadowNode->getConcreteProps().hasPaddingLeft &&
|
|
133
|
+
!textInputShadowNode->getConcreteProps().hasPaddingHorizontal) {
|
|
134
|
+
changedPadding = true;
|
|
135
|
+
result[YGEdgeStart] = theme[YGEdgeStart];
|
|
136
|
+
}
|
|
137
|
+
if (!textInputShadowNode->getConcreteProps().hasPadding &&
|
|
138
|
+
!textInputShadowNode->getConcreteProps().hasPaddingEnd &&
|
|
139
|
+
!textInputShadowNode->getConcreteProps().hasPaddingRight &&
|
|
140
|
+
!textInputShadowNode->getConcreteProps().hasPaddingHorizontal) {
|
|
141
|
+
changedPadding = true;
|
|
142
|
+
result[YGEdgeEnd] = theme[YGEdgeEnd];
|
|
143
|
+
}
|
|
144
|
+
if (!textInputShadowNode->getConcreteProps().hasPadding &&
|
|
145
|
+
!textInputShadowNode->getConcreteProps().hasPaddingTop &&
|
|
146
|
+
!textInputShadowNode->getConcreteProps().hasPaddingVertical) {
|
|
147
|
+
changedPadding = true;
|
|
148
|
+
result[YGEdgeTop] = theme[YGEdgeTop];
|
|
149
|
+
}
|
|
150
|
+
if (!textInputShadowNode->getConcreteProps().hasPadding &&
|
|
151
|
+
!textInputShadowNode->getConcreteProps().hasPaddingBottom &&
|
|
152
|
+
!textInputShadowNode->getConcreteProps().hasPaddingVertical) {
|
|
153
|
+
changedPadding = true;
|
|
154
|
+
result[YGEdgeBottom] = theme[YGEdgeBottom];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// If the TextInput initially does not have paddingLeft or paddingStart, a
|
|
158
|
+
// paddingStart may be set from the theme. If that happens, when there's a
|
|
159
|
+
// paddingLeft update, we must explicitly unset paddingStart... (same with
|
|
160
|
+
// paddingEnd)
|
|
161
|
+
// TODO: support RTL
|
|
162
|
+
if ((textInputShadowNode->getConcreteProps().hasPadding ||
|
|
163
|
+
textInputShadowNode->getConcreteProps().hasPaddingLeft ||
|
|
164
|
+
textInputShadowNode->getConcreteProps().hasPaddingHorizontal) &&
|
|
165
|
+
!textInputShadowNode->getConcreteProps().hasPaddingStart) {
|
|
166
|
+
result[YGEdgeStart] = YGValueUndefined;
|
|
167
|
+
}
|
|
168
|
+
if ((textInputShadowNode->getConcreteProps().hasPadding ||
|
|
169
|
+
textInputShadowNode->getConcreteProps().hasPaddingRight ||
|
|
170
|
+
textInputShadowNode->getConcreteProps().hasPaddingHorizontal) &&
|
|
171
|
+
!textInputShadowNode->getConcreteProps().hasPaddingEnd) {
|
|
172
|
+
result[YGEdgeEnd] = YGValueUndefined;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Note that this is expensive: on every adopt, we need to set the Yoga
|
|
176
|
+
// props again, which normally only happens during prop parsing. Every
|
|
177
|
+
// commit, state update, etc, will incur this cost.
|
|
178
|
+
if (changedPadding) {
|
|
179
|
+
// Set new props on node
|
|
180
|
+
const_cast<WindowsTextInputProps &>(textInputShadowNode->getConcreteProps()).yogaStyle.padding() = result;
|
|
181
|
+
// Communicate new props to Yoga part of the node
|
|
182
|
+
textInputShadowNode->updateYogaProps();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
textInputShadowNode->dirtyLayout();
|
|
187
|
+
textInputShadowNode->enableMeasurement();
|
|
188
|
+
|
|
189
|
+
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private:
|
|
193
|
+
SharedTextLayoutManager textLayoutManager_;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
} // namespace react
|
|
197
|
+
} // namespace facebook
|