@office-iss/react-native-win32 0.0.0-canary.259 → 0.0.0-canary.261

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.
Files changed (125) hide show
  1. package/.flowconfig +4 -3
  2. package/CHANGELOG.json +31 -1
  3. package/CHANGELOG.md +20 -4
  4. package/Libraries/Animated/AnimatedImplementation.js +7 -7
  5. package/Libraries/Animated/animations/Animation.js +10 -0
  6. package/Libraries/Animated/animations/TimingAnimation.js +1 -0
  7. package/Libraries/Animated/components/AnimatedScrollView.js +2 -2
  8. package/Libraries/Animated/createAnimatedComponent.js +1 -1
  9. package/Libraries/Animated/useAnimatedProps.js +71 -4
  10. package/Libraries/Blob/FileReader.js +1 -1
  11. package/Libraries/Blob/URL.js +2 -62
  12. package/Libraries/Blob/URLSearchParams.js +71 -0
  13. package/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +1 -1
  14. package/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js +1 -1
  15. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +3 -0
  16. package/Libraries/Components/ScrollView/ScrollView.js +5 -5
  17. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +3 -3
  18. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +1 -1
  19. package/Libraries/Components/StatusBar/StatusBar.js +3 -1
  20. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +3 -0
  21. package/Libraries/Components/TextInput/TextInput.d.ts +32 -2
  22. package/Libraries/Components/TextInput/TextInput.js +19 -10
  23. package/Libraries/Components/TextInput/TextInput.win32.js +19 -10
  24. package/Libraries/Components/View/ReactNativeStyleAttributes.js +11 -0
  25. package/Libraries/Components/View/ReactNativeViewAttributes.js +2 -0
  26. package/Libraries/Components/View/ReactNativeViewAttributes.win32.js +2 -0
  27. package/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
  28. package/Libraries/Components/View/ViewNativeComponent.js +6 -0
  29. package/Libraries/Components/View/ViewPropTypes.js +14 -0
  30. package/Libraries/Components/View/ViewPropTypes.win32.js +14 -0
  31. package/Libraries/Core/InitializeCore.js +1 -1
  32. package/Libraries/Core/ReactNativeVersion.js +1 -1
  33. package/Libraries/Core/setUpErrorHandling.js +7 -1
  34. package/Libraries/Image/AssetSourceResolver.js +28 -1
  35. package/Libraries/Image/Image.android.js +9 -14
  36. package/Libraries/Image/Image.ios.js +11 -22
  37. package/Libraries/Image/Image.win32.js +10 -21
  38. package/Libraries/Image/ImageBackground.js +1 -8
  39. package/Libraries/Image/ImageUtils.js +9 -9
  40. package/Libraries/Image/ImageViewNativeComponent.js +3 -0
  41. package/Libraries/Inspector/NetworkOverlay.js +1 -1
  42. package/Libraries/Lists/FlatList.js +1 -1
  43. package/Libraries/Lists/SectionList.js +1 -1
  44. package/Libraries/Lists/SectionListModern.js +3 -3
  45. package/Libraries/LogBox/Data/LogBoxData.js +30 -4
  46. package/Libraries/NativeComponent/BaseViewConfig.android.js +1 -0
  47. package/Libraries/NativeComponent/BaseViewConfig.ios.js +4 -0
  48. package/Libraries/NativeComponent/BaseViewConfig.win32.js +4 -0
  49. package/Libraries/NativeComponent/NativeComponentRegistry.js +13 -20
  50. package/Libraries/NativeComponent/StaticViewConfigValidator.js +0 -21
  51. package/Libraries/Network/XMLHttpRequest.js +4 -2
  52. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricHostComponent.js +1 -1
  53. package/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance.js +5 -5
  54. package/Libraries/ReactNative/RendererImplementation.js +26 -4
  55. package/Libraries/ReactNative/getNativeComponentAttributes.js +8 -0
  56. package/Libraries/Renderer/shims/ReactNativeTypes.js +9 -4
  57. package/Libraries/StyleSheet/StyleSheet.js +1 -1
  58. package/Libraries/StyleSheet/StyleSheet.win32.js +1 -1
  59. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +11 -0
  60. package/Libraries/StyleSheet/StyleSheetTypes.js +14 -2
  61. package/Libraries/StyleSheet/processBackgroundImage.js +384 -0
  62. package/Libraries/StyleSheet/processFilter.js +4 -4
  63. package/Libraries/Text/Text.js +7 -6
  64. package/Libraries/Text/Text.win32.js +7 -6
  65. package/Libraries/Text/TextNativeComponent.js +7 -0
  66. package/Libraries/Text/TextNativeComponent.win32.js +7 -0
  67. package/Libraries/Utilities/Appearance.js +65 -73
  68. package/Libraries/Utilities/DevLoadingView.js +2 -4
  69. package/Libraries/Utilities/ReactNativeTestTools.js +1 -1
  70. package/Libraries/Utilities/stringifyViewConfig.js +22 -0
  71. package/Libraries/Utilities/useColorScheme.js +3 -3
  72. package/Libraries/WebSocket/WebSocket.js +1 -1
  73. package/flow/jest.js +2 -2
  74. package/index.js +2 -1
  75. package/index.win32.js +2 -1
  76. package/jest/mockModal.js +1 -3
  77. package/jest/mockScrollView.js +1 -1
  78. package/jest/renderer.js +2 -2
  79. package/jest/setup.js +8 -12
  80. package/overrides.json +12 -12
  81. package/package.json +14 -14
  82. package/src/private/{core/components → components}/HScrollViewNativeComponents.js +8 -8
  83. package/src/private/{core/components → components}/VScrollViewNativeComponents.js +7 -7
  84. package/src/private/{core/components → components}/useSyncOnScroll.js +2 -2
  85. package/src/private/featureflags/ReactNativeFeatureFlags.js +93 -10
  86. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +16 -3
  87. package/src/private/hooks/DebouncedEffectImplementation.js +148 -0
  88. package/src/private/hooks/useDebouncedEffect.js +23 -0
  89. package/{Libraries/Core → src/private/renderer/errorhandling}/ErrorHandlers.js +5 -4
  90. package/src/private/setup/setUpDOM.js +28 -0
  91. package/src/private/setup/setUpIntersectionObserver.js +27 -0
  92. package/src/private/setup/setUpMutationObserver.js +26 -0
  93. package/src/private/setup/setUpPerformanceObserver.js +64 -0
  94. package/src/private/specs/modules/NativeAppearance.js +3 -3
  95. package/src/private/specs/modules/NativeDebuggerSessionObserver.js +23 -0
  96. package/src/private/webapis/dom/nodes/ReadOnlyNode.js +6 -4
  97. package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver}/IntersectionObserver.js +5 -3
  98. package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver}/IntersectionObserverEntry.js +3 -3
  99. package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver}/IntersectionObserverManager.js +14 -17
  100. package/src/private/{specs/modules → webapis/intersectionobserver/specs}/NativeIntersectionObserver.js +2 -2
  101. package/{Libraries/IntersectionObserver → src/private/webapis/intersectionobserver/specs}/__mocks__/NativeIntersectionObserver.js +4 -4
  102. package/{Libraries/MutationObserver → src/private/webapis/mutationobserver}/MutationObserver.js +5 -3
  103. package/{Libraries/MutationObserver → src/private/webapis/mutationobserver}/MutationObserverManager.js +24 -15
  104. package/{Libraries/MutationObserver → src/private/webapis/mutationobserver}/MutationRecord.js +4 -6
  105. package/src/private/{specs/modules → webapis/mutationobserver/specs}/NativeMutationObserver.js +2 -2
  106. package/{Libraries/MutationObserver → src/private/webapis/mutationobserver/specs}/__mocks__/NativeMutationObserver.js +5 -5
  107. package/src/private/webapis/performance/{EventCounts.js → EventTiming.js} +65 -3
  108. package/src/private/webapis/performance/LongTasks.js +39 -0
  109. package/src/private/webapis/performance/Performance.js +22 -9
  110. package/src/private/webapis/performance/PerformanceEntry.js +35 -17
  111. package/src/private/webapis/performance/PerformanceObserver.js +29 -43
  112. package/src/private/webapis/performance/RawPerformanceEntry.js +19 -1
  113. package/src/private/webapis/performance/UserTiming.js +17 -12
  114. package/src/private/webapis/performance/specs/NativePerformanceObserver.js +1 -1
  115. package/src-win/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
  116. package/types/experimental.d.ts +10 -2
  117. package/Libraries/Core/setUpIntersectionObserver.js +0 -16
  118. package/Libraries/Core/setUpMutationObserver.js +0 -16
  119. package/Libraries/Core/setUpPerformanceObserver.js +0 -18
  120. package/Libraries/IntersectionObserver/NativeIntersectionObserver.js +0 -13
  121. package/Libraries/MutationObserver/NativeMutationObserver.js +0 -13
  122. package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +0 -135
  123. package/src/private/core/setUpDOM.js +0 -18
  124. package/src/private/webapis/performance/PerformanceEventTiming.js +0 -55
  125. /package/src/private/{core → styles}/composeStyles.js +0 -0
@@ -0,0 +1,384 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @flow strict-local
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ import type {ProcessedColorValue} from './processColor';
14
+ import type {GradientValue} from './StyleSheetTypes';
15
+
16
+ const processColor = require('./processColor').default;
17
+ const DIRECTION_REGEX =
18
+ /^to\s+(?:top|bottom|left|right)(?:\s+(?:top|bottom|left|right))?/;
19
+ const ANGLE_UNIT_REGEX = /^([+-]?\d*\.?\d+)(deg|grad|rad|turn)$/i;
20
+
21
+ const TO_BOTTOM_START_END_POINTS = {
22
+ start: {x: 0.5, y: 0},
23
+ end: {x: 0.5, y: 1},
24
+ };
25
+
26
+ type ParsedGradientValue = {
27
+ type: 'linearGradient',
28
+ start: {x: number, y: number},
29
+ end: {x: number, y: number},
30
+ colorStops: $ReadOnlyArray<{
31
+ color: ProcessedColorValue,
32
+ position: number,
33
+ }>,
34
+ };
35
+
36
+ export default function processBackgroundImage(
37
+ backgroundImage: ?($ReadOnlyArray<GradientValue> | string),
38
+ ): $ReadOnlyArray<ParsedGradientValue> {
39
+ let result: $ReadOnlyArray<ParsedGradientValue> = [];
40
+ if (backgroundImage == null) {
41
+ return result;
42
+ }
43
+
44
+ if (typeof backgroundImage === 'string') {
45
+ result = parseCSSLinearGradient(backgroundImage);
46
+ } else if (Array.isArray(backgroundImage)) {
47
+ for (const bgImage of backgroundImage) {
48
+ const processedColorStops: Array<{
49
+ color: ProcessedColorValue,
50
+ position: number | null,
51
+ }> = [];
52
+ for (let index = 0; index < bgImage.colorStops.length; index++) {
53
+ const colorStop = bgImage.colorStops[index];
54
+ const processedColor = processColor(colorStop.color);
55
+ if (processedColor == null) {
56
+ // If a color is invalid, return an empty array and do not apply gradient. Same as web.
57
+ return [];
58
+ }
59
+ if (colorStop.positions != null && colorStop.positions.length > 0) {
60
+ for (const position of colorStop.positions) {
61
+ if (position.endsWith('%')) {
62
+ processedColorStops.push({
63
+ color: processedColor,
64
+ position: parseFloat(position) / 100,
65
+ });
66
+ } else {
67
+ // If a position is invalid, return an empty array and do not apply gradient. Same as web.
68
+ return [];
69
+ }
70
+ }
71
+ } else {
72
+ processedColorStops.push({
73
+ color: processedColor,
74
+ position: null,
75
+ });
76
+ }
77
+ }
78
+
79
+ let points: {
80
+ start: ParsedGradientValue['start'],
81
+ end: ParsedGradientValue['end'],
82
+ } | null = null;
83
+
84
+ if (typeof bgImage.direction === 'undefined') {
85
+ points = TO_BOTTOM_START_END_POINTS;
86
+ } else if (ANGLE_UNIT_REGEX.test(bgImage.direction)) {
87
+ const angle = parseAngle(bgImage.direction);
88
+ if (angle != null) {
89
+ points = calculateStartEndPointsFromAngle(angle);
90
+ }
91
+ } else if (DIRECTION_REGEX.test(bgImage.direction)) {
92
+ const processedPoints = calculateStartEndPointsFromDirection(
93
+ bgImage.direction,
94
+ );
95
+ if (processedPoints != null) {
96
+ points = processedPoints;
97
+ }
98
+ }
99
+
100
+ const fixedColorStops = getFixedColorStops(processedColorStops);
101
+
102
+ if (points != null) {
103
+ result = result.concat({
104
+ type: 'linearGradient',
105
+ start: points.start,
106
+ end: points.end,
107
+ colorStops: fixedColorStops,
108
+ });
109
+ }
110
+ }
111
+ }
112
+
113
+ return result;
114
+ }
115
+
116
+ function parseCSSLinearGradient(
117
+ cssString: string,
118
+ ): $ReadOnlyArray<ParsedGradientValue> {
119
+ const gradients = [];
120
+ let match;
121
+ const linearGradientRegex = /linear-gradient\s*\(((?:\([^)]*\)|[^())])*)\)/gi;
122
+
123
+ while ((match = linearGradientRegex.exec(cssString))) {
124
+ const gradientContent = match[1];
125
+ const parts = gradientContent.split(',');
126
+ let points = TO_BOTTOM_START_END_POINTS;
127
+ const trimmedDirection = parts[0].trim().toLowerCase();
128
+ const colorStopRegex =
129
+ /\s*((?:(?:rgba?|hsla?)\s*\([^)]+\))|#[0-9a-fA-F]+|[a-zA-Z]+)(?:\s+(-?[0-9.]+%?)(?:\s+(-?[0-9.]+%?))?)?\s*/gi;
130
+
131
+ if (ANGLE_UNIT_REGEX.test(trimmedDirection)) {
132
+ const angle = parseAngle(trimmedDirection);
133
+ if (angle != null) {
134
+ points = calculateStartEndPointsFromAngle(angle);
135
+ parts.shift();
136
+ } else {
137
+ // If an angle is invalid, return an empty array and do not apply any gradient. Same as web.
138
+ return [];
139
+ }
140
+ } else if (DIRECTION_REGEX.test(trimmedDirection)) {
141
+ const parsedPoints =
142
+ calculateStartEndPointsFromDirection(trimmedDirection);
143
+ if (parsedPoints != null) {
144
+ points = parsedPoints;
145
+ parts.shift();
146
+ } else {
147
+ // If a direction is invalid, return an empty array and do not apply any gradient. Same as web.
148
+ return [];
149
+ }
150
+ } else if (!colorStopRegex.test(trimmedDirection)) {
151
+ // If first part is not an angle/direction or a color stop, return an empty array and do not apply any gradient. Same as web.
152
+ return [];
153
+ }
154
+ colorStopRegex.lastIndex = 0;
155
+
156
+ const colorStops = [];
157
+ const fullColorStopsStr = parts.join(',');
158
+ let colorStopMatch;
159
+ while ((colorStopMatch = colorStopRegex.exec(fullColorStopsStr))) {
160
+ const [, color, position1, position2] = colorStopMatch;
161
+ const processedColor = processColor(color.trim().toLowerCase());
162
+ if (processedColor == null) {
163
+ // If a color is invalid, return an empty array and do not apply any gradient. Same as web.
164
+ return [];
165
+ }
166
+
167
+ if (typeof position1 !== 'undefined') {
168
+ if (position1.endsWith('%')) {
169
+ colorStops.push({
170
+ color: processedColor,
171
+ position: parseFloat(position1) / 100,
172
+ });
173
+ } else {
174
+ // If a position is invalid, return an empty array and do not apply any gradient. Same as web.
175
+ return [];
176
+ }
177
+ } else {
178
+ colorStops.push({
179
+ color: processedColor,
180
+ position: null,
181
+ });
182
+ }
183
+
184
+ if (typeof position2 !== 'undefined') {
185
+ if (position2.endsWith('%')) {
186
+ colorStops.push({
187
+ color: processedColor,
188
+ position: parseFloat(position2) / 100,
189
+ });
190
+ } else {
191
+ // If a position is invalid, return an empty array and do not apply any gradient. Same as web.
192
+ return [];
193
+ }
194
+ }
195
+ }
196
+
197
+ const fixedColorStops = getFixedColorStops(colorStops);
198
+
199
+ gradients.push({
200
+ type: 'linearGradient',
201
+ start: points.start,
202
+ end: points.end,
203
+ colorStops: fixedColorStops,
204
+ });
205
+ }
206
+
207
+ return gradients;
208
+ }
209
+
210
+ function calculateStartEndPointsFromDirection(direction: string): ?{
211
+ start: {x: number, y: number},
212
+ end: {x: number, y: number},
213
+ } {
214
+ // Remove extra whitespace
215
+ const normalizedDirection = direction.replace(/\s+/g, ' ');
216
+
217
+ switch (normalizedDirection) {
218
+ case 'to right':
219
+ return {
220
+ start: {x: 0, y: 0.5},
221
+ end: {x: 1, y: 0.5},
222
+ };
223
+ case 'to left':
224
+ return {
225
+ start: {x: 1, y: 0.5},
226
+ end: {x: 0, y: 0.5},
227
+ };
228
+ case 'to bottom':
229
+ return TO_BOTTOM_START_END_POINTS;
230
+ case 'to top':
231
+ return {
232
+ start: {x: 0.5, y: 1},
233
+ end: {x: 0.5, y: 0},
234
+ };
235
+ case 'to bottom right':
236
+ case 'to right bottom':
237
+ return {
238
+ start: {x: 0, y: 0},
239
+ end: {x: 1, y: 1},
240
+ };
241
+ case 'to top left':
242
+ case 'to left top':
243
+ return {
244
+ start: {x: 1, y: 1},
245
+ end: {x: 0, y: 0},
246
+ };
247
+ case 'to bottom left':
248
+ case 'to left bottom':
249
+ return {
250
+ start: {x: 1, y: 0},
251
+ end: {x: 0, y: 1},
252
+ };
253
+ case 'to top right':
254
+ case 'to right top':
255
+ return {
256
+ start: {x: 0, y: 1},
257
+ end: {x: 1, y: 0},
258
+ };
259
+ default:
260
+ return null;
261
+ }
262
+ }
263
+
264
+ function calculateStartEndPointsFromAngle(angleRadians: number): {
265
+ start: {x: number, y: number},
266
+ end: {x: number, y: number},
267
+ } {
268
+ // Normalize angle to be between 0 and 2π
269
+ let angleRadiansNormalized = angleRadians % (2 * Math.PI);
270
+ if (angleRadiansNormalized < 0) {
271
+ angleRadiansNormalized += 2 * Math.PI;
272
+ }
273
+
274
+ const endX = 0.5 + 0.5 * Math.sin(angleRadiansNormalized);
275
+ const endY = 0.5 - 0.5 * Math.cos(angleRadiansNormalized);
276
+
277
+ const startX = 1 - endX;
278
+ const startY = 1 - endY;
279
+
280
+ return {
281
+ start: {x: startX, y: startY},
282
+ end: {x: endX, y: endY},
283
+ };
284
+ }
285
+
286
+ function parseAngle(angle: string): ?number {
287
+ const match = angle.match(ANGLE_UNIT_REGEX);
288
+ if (!match) {
289
+ return null;
290
+ }
291
+
292
+ const [, value, unit] = match;
293
+
294
+ const numericValue = parseFloat(value);
295
+ switch (unit) {
296
+ case 'deg':
297
+ return (numericValue * Math.PI) / 180;
298
+ case 'grad':
299
+ return (numericValue * Math.PI) / 200;
300
+ case 'rad':
301
+ return numericValue;
302
+ case 'turn':
303
+ return numericValue * 2 * Math.PI;
304
+ default:
305
+ return null;
306
+ }
307
+ }
308
+
309
+ // https://drafts.csswg.org/css-images-4/#color-stop-fixup
310
+ function getFixedColorStops(
311
+ colorStops: $ReadOnlyArray<{
312
+ color: ProcessedColorValue,
313
+ position: number | null,
314
+ }>,
315
+ ): Array<{
316
+ color: ProcessedColorValue,
317
+ position: number,
318
+ }> {
319
+ let fixedColorStops: Array<{
320
+ color: ProcessedColorValue,
321
+ position: number,
322
+ }> = [];
323
+ let hasNullPositions = false;
324
+ let maxPositionSoFar = colorStops[0].position ?? 0;
325
+ for (let i = 0; i < colorStops.length; i++) {
326
+ const colorStop = colorStops[i];
327
+ let newPosition = colorStop.position;
328
+ if (newPosition === null) {
329
+ // Step 1:
330
+ // If the first color stop does not have a position,
331
+ // set its position to 0%. If the last color stop does not have a position,
332
+ // set its position to 100%.
333
+ if (i === 0) {
334
+ newPosition = 0;
335
+ } else if (i === colorStops.length - 1) {
336
+ newPosition = 1;
337
+ }
338
+ }
339
+ // Step 2:
340
+ // If a color stop or transition hint has a position
341
+ // that is less than the specified position of any color stop or transition hint
342
+ // before it in the list, set its position to be equal to the
343
+ // largest specified position of any color stop or transition hint before it.
344
+ if (newPosition !== null) {
345
+ newPosition = Math.max(newPosition, maxPositionSoFar);
346
+ fixedColorStops[i] = {
347
+ color: colorStop.color,
348
+ position: newPosition,
349
+ };
350
+ maxPositionSoFar = newPosition;
351
+ } else {
352
+ hasNullPositions = true;
353
+ }
354
+ }
355
+
356
+ // Step 3:
357
+ // If any color stop still does not have a position,
358
+ // then, for each run of adjacent color stops without positions,
359
+ // set their positions so that they are evenly spaced between the preceding and
360
+ // following color stops with positions.
361
+ if (hasNullPositions) {
362
+ let lastDefinedIndex = 0;
363
+ for (let i = 1; i < fixedColorStops.length; i++) {
364
+ if (fixedColorStops[i] !== undefined) {
365
+ const unpositionedStops = i - lastDefinedIndex - 1;
366
+ if (unpositionedStops > 0) {
367
+ const startPosition = fixedColorStops[lastDefinedIndex].position;
368
+ const endPosition = fixedColorStops[i].position;
369
+ const increment =
370
+ (endPosition - startPosition) / (unpositionedStops + 1);
371
+ for (let j = 1; j <= unpositionedStops; j++) {
372
+ fixedColorStops[lastDefinedIndex + j] = {
373
+ color: colorStops[lastDefinedIndex + j].color,
374
+ position: startPosition + increment * j,
375
+ };
376
+ }
377
+ }
378
+ lastDefinedIndex = i;
379
+ }
380
+ }
381
+ }
382
+
383
+ return fixedColorStops;
384
+ }
@@ -44,8 +44,8 @@ export default function processFilter(
44
44
  }
45
45
 
46
46
  if (typeof filter === 'string') {
47
- // matches on functions with args like "drop-shadow(1.5)"
48
- const regex = /([\w-]+)\(([^)]+)\)/g;
47
+ // matches on functions with args and nested functions like "drop-shadow(10 10 10 rgba(0, 0, 0, 1))"
48
+ const regex = /([\w-]+)\(([^()]*|\([^()]*\)|[^()]*\([^()]*\)[^()]*)\)/g;
49
49
  let matches;
50
50
 
51
51
  while ((matches = regex.exec(filter))) {
@@ -254,8 +254,8 @@ function parseDropShadowString(rawDropShadow: string): ?DropShadowPrimitive {
254
254
  let lengthCount = 0;
255
255
  let keywordDetectedAfterLength = false;
256
256
 
257
- // split on all whitespaces
258
- for (const arg of rawDropShadow.split(/\s+/)) {
257
+ // split args by all whitespaces that are not in parenthesis
258
+ for (const arg of rawDropShadow.split(/\s+(?![^(]*\))/)) {
259
259
  const processedColor = processColor(arg);
260
260
  if (processedColor != null) {
261
261
  if (dropShadow.color != null) {
@@ -8,6 +8,7 @@
8
8
  * @format
9
9
  */
10
10
 
11
+ import type {TextStyleProp} from '../StyleSheet/StyleSheet';
11
12
  import type {____TextStyle_Internal as TextStyleInternal} from '../StyleSheet/StyleSheetTypes';
12
13
  import type {PressEvent} from '../Types/CoreEventTypes';
13
14
  import type {NativeTextProps} from './TextNativeComponent';
@@ -133,7 +134,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
133
134
 
134
135
  let _selectable = selectable;
135
136
 
136
- let processedStyle: ?TextStyleInternal = flattenStyle(_style);
137
+ let processedStyle = flattenStyle<TextStyleProp>(_style);
137
138
  if (processedStyle != null) {
138
139
  let overrides: ?{...TextStyleInternal} = null;
139
140
  if (typeof processedStyle.fontWeight === 'number') {
@@ -158,7 +159,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
158
159
 
159
160
  if (overrides != null) {
160
161
  // $FlowFixMe[incompatible-type]
161
- processedStyle = [processedStyle, overrides];
162
+ _style = [_style, overrides];
162
163
  }
163
164
  }
164
165
 
@@ -178,7 +179,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
178
179
  numberOfLines: _numberOfLines,
179
180
  selectable: _selectable,
180
181
  selectionColor: _selectionColor,
181
- style: processedStyle,
182
+ style: _style,
182
183
  disabled: disabled,
183
184
  children,
184
185
  }}
@@ -212,7 +213,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
212
213
  ref={forwardedRef}
213
214
  selectable={_selectable}
214
215
  selectionColor={_selectionColor}
215
- style={processedStyle}
216
+ style={_style}
216
217
  disabled={disabled}>
217
218
  {children}
218
219
  </NativeVirtualText>
@@ -256,7 +257,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
256
257
  numberOfLines: _numberOfLines,
257
258
  selectable: _selectable,
258
259
  selectionColor: _selectionColor,
259
- style: processedStyle,
260
+ style: _style,
260
261
  children,
261
262
  }}
262
263
  textPressabilityProps={{
@@ -291,7 +292,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
291
292
  ref={forwardedRef}
292
293
  selectable={_selectable}
293
294
  selectionColor={_selectionColor}
294
- style={processedStyle}>
295
+ style={_style}>
295
296
  {children}
296
297
  </NativeText>
297
298
  );
@@ -8,6 +8,7 @@
8
8
  * @format
9
9
  */
10
10
 
11
+ import type {TextStyleProp} from '../StyleSheet/StyleSheet';
11
12
  import type {____TextStyle_Internal as TextStyleInternal} from '../StyleSheet/StyleSheetTypes';
12
13
  import type {PressEvent} from '../Types/CoreEventTypes';
13
14
  import type {NativeTextProps} from './TextNativeComponent';
@@ -157,7 +158,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
157
158
 
158
159
  let _selectable = selectable;
159
160
 
160
- let processedStyle: ?TextStyleInternal = flattenStyle(_style);
161
+ let processedStyle = flattenStyle<TextStyleProp>(_style);
161
162
  if (processedStyle != null) {
162
163
  let overrides: ?{...TextStyleInternal} = null;
163
164
  if (typeof processedStyle.fontWeight === 'number') {
@@ -182,7 +183,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
182
183
 
183
184
  if (overrides != null) {
184
185
  // $FlowFixMe[incompatible-type]
185
- processedStyle = [processedStyle, overrides];
186
+ _style = [_style, overrides];
186
187
  }
187
188
  }
188
189
 
@@ -208,7 +209,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
208
209
  numberOfLines: _numberOfLines,
209
210
  selectable: _selectable,
210
211
  selectionColor: _selectionColor,
211
- style: processedStyle,
212
+ style: _style,
212
213
  disabled: disabled,
213
214
  children,
214
215
  }}
@@ -248,7 +249,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
248
249
  ref={forwardedRef}
249
250
  selectable={_selectable}
250
251
  selectionColor={_selectionColor}
251
- style={processedStyle}
252
+ style={_style}
252
253
  disabled={disabled}>
253
254
  {children}
254
255
  </NativeVirtualText>
@@ -298,7 +299,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
298
299
  numberOfLines: _numberOfLines,
299
300
  selectable: _selectable,
300
301
  selectionColor: _selectionColor,
301
- style: processedStyle,
302
+ style: _style,
302
303
  children,
303
304
  }}
304
305
  textPressabilityProps={{
@@ -339,7 +340,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
339
340
  ref={forwardedRef}
340
341
  selectable={_selectable}
341
342
  selectionColor={_selectionColor}
342
- style={processedStyle}>
343
+ style={_style}>
343
344
  {children}
344
345
  </NativeText>
345
346
  );
@@ -16,6 +16,7 @@ import type {TextProps} from './TextProps';
16
16
  import {createViewConfig} from '../NativeComponent/ViewConfig';
17
17
  import UIManager from '../ReactNative/UIManager';
18
18
  import createReactNativeComponentClass from '../Renderer/shims/createReactNativeComponentClass';
19
+ import Platform from '../Utilities/Platform';
19
20
 
20
21
  export type NativeTextProps = $ReadOnly<{
21
22
  ...TextProps,
@@ -48,6 +49,12 @@ const textViewConfig = {
48
49
  dataDetectorType: true,
49
50
  android_hyphenationFrequency: true,
50
51
  lineBreakStrategyIOS: true,
52
+ // boxShadow is currently per-component on Android instead of being on BaseViewConfig yet
53
+ ...(Platform.OS === 'android' && {
54
+ experimental_boxShadow: {
55
+ process: require('../StyleSheet/processBoxShadow').default,
56
+ },
57
+ }),
51
58
  },
52
59
  directEventTypes: {
53
60
  topTextLayout: {
@@ -16,6 +16,7 @@ import type {TextProps} from './TextProps';
16
16
  import {createViewConfig} from '../NativeComponent/ViewConfig';
17
17
  import UIManager from '../ReactNative/UIManager';
18
18
  import createReactNativeComponentClass from '../Renderer/shims/createReactNativeComponentClass';
19
+ import Platform from '../Utilities/Platform';
19
20
 
20
21
  export type NativeTextProps = $ReadOnly<{
21
22
  ...TextProps,
@@ -82,6 +83,12 @@ const textViewConfig = {
82
83
  textStyle: true,
83
84
  tooltip: true,
84
85
  // Windows]
86
+ // boxShadow is currently per-component on Android instead of being on BaseViewConfig yet
87
+ ...(Platform.OS === 'android' && {
88
+ experimental_boxShadow: {
89
+ process: require('../StyleSheet/processBoxShadow').default,
90
+ },
91
+ }),
85
92
  },
86
93
  directEventTypes: {
87
94
  topTextLayout: {