@office-iss/react-native-win32 0.0.0-canary.260 → 0.0.0-canary.262
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 +4 -3
- package/CHANGELOG.json +37 -1
- package/CHANGELOG.md +21 -4
- package/Libraries/Animated/nodes/AnimatedObject.js +2 -5
- package/Libraries/Animated/nodes/AnimatedProps.js +2 -0
- package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +0 -3
- package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +0 -3
- package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +0 -3
- package/Libraries/Components/TextInput/TextInput.js +20 -24
- package/Libraries/Components/TextInput/TextInput.win32.js +20 -24
- package/Libraries/Components/View/ViewNativeComponent.js +0 -7
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Image/ImageViewNativeComponent.js +0 -3
- package/Libraries/Lists/SectionListModern.js +2 -2
- package/Libraries/LogBox/Data/LogBoxData.js +8 -14
- package/Libraries/Modal/Modal.js +0 -1
- package/Libraries/NativeComponent/BaseViewConfig.android.js +6 -0
- package/Libraries/NativeComponent/NativeComponentRegistry.js +13 -20
- package/Libraries/NativeComponent/StaticViewConfigValidator.js +0 -21
- package/Libraries/ReactNative/RendererImplementation.js +2 -2
- package/Libraries/Renderer/shims/ReactNativeTypes.js +9 -4
- package/Libraries/StyleSheet/StyleSheetTypes.d.ts +3 -3
- package/Libraries/StyleSheet/StyleSheetTypes.js +1 -1
- package/Libraries/StyleSheet/processBackgroundImage.js +137 -39
- package/Libraries/StyleSheet/processBoxShadow.js +1 -1
- package/Libraries/StyleSheet/processFilter.js +9 -5
- package/Libraries/Text/Text.win32.js +1 -1
- package/Libraries/Text/TextNativeComponent.js +0 -6
- package/Libraries/Text/TextNativeComponent.win32.js +0 -6
- package/Libraries/Utilities/Appearance.js +108 -84
- package/Libraries/Utilities/DevLoadingView.js +2 -4
- package/Libraries/Utilities/HMRClient.js +1 -1
- package/Libraries/Utilities/createPerformanceLogger.js +0 -9
- package/Libraries/Utilities/stringifyViewConfig.js +22 -0
- package/Libraries/Utilities/useColorScheme.js +3 -3
- package/Libraries/promiseRejectionTrackingOptions.js +1 -1
- package/index.js +1 -1
- package/index.win32.js +1 -1
- package/jest/setup.js +0 -4
- package/overrides.json +5 -5
- package/package.json +13 -13
- package/src/private/featureflags/ReactNativeFeatureFlags.js +27 -6
- package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +5 -2
- package/src/private/fusebox/FuseboxSessionObserver.js +42 -0
- package/src/private/specs/modules/NativeAppearance.js +3 -3
- package/src/private/webapis/intersectionobserver/IntersectionObserver.js +4 -2
- package/src/private/webapis/intersectionobserver/IntersectionObserverManager.js +9 -9
- package/src/private/webapis/mutationobserver/MutationObserver.js +4 -2
- package/src/private/webapis/mutationobserver/MutationObserverManager.js +19 -10
- package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +0 -135
- package/src/private/specs/modules/NativeDebuggerSessionObserver.js +0 -23
|
@@ -42,36 +42,37 @@ export default function processBackgroundImage(
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
if (typeof backgroundImage === 'string') {
|
|
45
|
-
result = parseCSSLinearGradient(backgroundImage);
|
|
45
|
+
result = parseCSSLinearGradient(backgroundImage.replace(/\n/g, ' '));
|
|
46
46
|
} else if (Array.isArray(backgroundImage)) {
|
|
47
47
|
for (const bgImage of backgroundImage) {
|
|
48
|
-
const processedColorStops
|
|
48
|
+
const processedColorStops: Array<{
|
|
49
|
+
color: ProcessedColorValue,
|
|
50
|
+
position: number | null,
|
|
51
|
+
}> = [];
|
|
49
52
|
for (let index = 0; index < bgImage.colorStops.length; index++) {
|
|
50
|
-
const
|
|
51
|
-
const processedColor = processColor(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// Currently we only support percentage and undefined value for color stop position.
|
|
55
|
-
if (typeof stop.position === 'undefined') {
|
|
56
|
-
processedPosition =
|
|
57
|
-
bgImage.colorStops.length === 1
|
|
58
|
-
? 1
|
|
59
|
-
: index / (bgImage.colorStops.length - 1);
|
|
60
|
-
} else if (stop.position.endsWith('%')) {
|
|
61
|
-
processedPosition = parseFloat(stop.position) / 100;
|
|
62
|
-
} else {
|
|
63
|
-
// If a color stop position is invalid, return an empty array and do not apply gradient. Same as web.
|
|
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.
|
|
64
57
|
return [];
|
|
65
58
|
}
|
|
66
|
-
|
|
67
|
-
|
|
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 {
|
|
68
72
|
processedColorStops.push({
|
|
69
73
|
color: processedColor,
|
|
70
|
-
position:
|
|
74
|
+
position: null,
|
|
71
75
|
});
|
|
72
|
-
} else {
|
|
73
|
-
// If a color is invalid, return an empty array and do not apply gradient. Same as web.
|
|
74
|
-
return [];
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
|
|
@@ -96,12 +97,14 @@ export default function processBackgroundImage(
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
const fixedColorStops = getFixedColorStops(processedColorStops);
|
|
101
|
+
|
|
99
102
|
if (points != null) {
|
|
100
103
|
result = result.concat({
|
|
101
104
|
type: 'linearGradient',
|
|
102
105
|
start: points.start,
|
|
103
106
|
end: points.end,
|
|
104
|
-
colorStops:
|
|
107
|
+
colorStops: fixedColorStops,
|
|
105
108
|
});
|
|
106
109
|
}
|
|
107
110
|
}
|
|
@@ -123,7 +126,7 @@ function parseCSSLinearGradient(
|
|
|
123
126
|
let points = TO_BOTTOM_START_END_POINTS;
|
|
124
127
|
const trimmedDirection = parts[0].trim().toLowerCase();
|
|
125
128
|
const colorStopRegex =
|
|
126
|
-
/\s*((?:(?:rgba?|hsla?)\s*\([^)]+\))|#[0-9a-fA-F]+|[a-zA-Z]+)(?:\s+([0-9.]+%?))?\s*/gi;
|
|
129
|
+
/\s*((?:(?:rgba?|hsla?)\s*\([^)]+\))|#[0-9a-fA-F]+|[a-zA-Z]+)(?:\s+(-?[0-9.]+%?)(?:\s+(-?[0-9.]+%?))?)?\s*/gi;
|
|
127
130
|
|
|
128
131
|
if (ANGLE_UNIT_REGEX.test(trimmedDirection)) {
|
|
129
132
|
const angle = parseAngle(trimmedDirection);
|
|
@@ -154,32 +157,50 @@ function parseCSSLinearGradient(
|
|
|
154
157
|
const fullColorStopsStr = parts.join(',');
|
|
155
158
|
let colorStopMatch;
|
|
156
159
|
while ((colorStopMatch = colorStopRegex.exec(fullColorStopsStr))) {
|
|
157
|
-
const [, color,
|
|
160
|
+
const [, color, position1, position2] = colorStopMatch;
|
|
158
161
|
const processedColor = processColor(color.trim().toLowerCase());
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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 {
|
|
163
178
|
colorStops.push({
|
|
164
179
|
color: processedColor,
|
|
165
|
-
position:
|
|
180
|
+
position: null,
|
|
166
181
|
});
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
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
|
+
}
|
|
170
194
|
}
|
|
171
195
|
}
|
|
172
196
|
|
|
197
|
+
const fixedColorStops = getFixedColorStops(colorStops);
|
|
198
|
+
|
|
173
199
|
gradients.push({
|
|
174
200
|
type: 'linearGradient',
|
|
175
201
|
start: points.start,
|
|
176
202
|
end: points.end,
|
|
177
|
-
colorStops:
|
|
178
|
-
color: stop.color,
|
|
179
|
-
position:
|
|
180
|
-
stop.position ??
|
|
181
|
-
(array.length === 1 ? 1 : index / (array.length - 1)),
|
|
182
|
-
})),
|
|
203
|
+
colorStops: fixedColorStops,
|
|
183
204
|
});
|
|
184
205
|
}
|
|
185
206
|
|
|
@@ -284,3 +305,80 @@ function parseAngle(angle: string): ?number {
|
|
|
284
305
|
return null;
|
|
285
306
|
}
|
|
286
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
|
+
}
|
|
@@ -33,7 +33,7 @@ export default function processBoxShadow(
|
|
|
33
33
|
|
|
34
34
|
const boxShadowList =
|
|
35
35
|
typeof rawBoxShadows === 'string'
|
|
36
|
-
? parseBoxShadowString(rawBoxShadows)
|
|
36
|
+
? parseBoxShadowString(rawBoxShadows.replace(/\n/g, ' '))
|
|
37
37
|
: rawBoxShadows;
|
|
38
38
|
|
|
39
39
|
for (const rawBoxShadow of boxShadowList) {
|
|
@@ -44,8 +44,10 @@ export default function processFilter(
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
if (typeof filter === 'string') {
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
filter = filter.replace(/\n/g, ' ');
|
|
48
|
+
|
|
49
|
+
// matches on functions with args and nested functions like "drop-shadow(10 10 10 rgba(0, 0, 0, 1))"
|
|
50
|
+
const regex = /([\w-]+)\(([^()]*|\([^()]*\)|[^()]*\([^()]*\)[^()]*)\)/g;
|
|
49
51
|
let matches;
|
|
50
52
|
|
|
51
53
|
while ((matches = regex.exec(filter))) {
|
|
@@ -80,7 +82,7 @@ export default function processFilter(
|
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
|
-
} else {
|
|
85
|
+
} else if (Array.isArray(filter)) {
|
|
84
86
|
for (const filterFunction of filter) {
|
|
85
87
|
const [filterName, filterValue] = Object.entries(filterFunction)[0];
|
|
86
88
|
if (filterName === 'dropShadow') {
|
|
@@ -107,6 +109,8 @@ export default function processFilter(
|
|
|
107
109
|
}
|
|
108
110
|
}
|
|
109
111
|
}
|
|
112
|
+
} else {
|
|
113
|
+
throw new TypeError(`${typeof filter} filter is not a string or array`);
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
return result;
|
|
@@ -254,8 +258,8 @@ function parseDropShadowString(rawDropShadow: string): ?DropShadowPrimitive {
|
|
|
254
258
|
let lengthCount = 0;
|
|
255
259
|
let keywordDetectedAfterLength = false;
|
|
256
260
|
|
|
257
|
-
// split
|
|
258
|
-
for (const arg of rawDropShadow.split(/\s
|
|
261
|
+
// split args by all whitespaces that are not in parenthesis
|
|
262
|
+
for (const arg of rawDropShadow.split(/\s+(?![^(]*\))/)) {
|
|
259
263
|
const processedColor = processColor(arg);
|
|
260
264
|
if (processedColor != null) {
|
|
261
265
|
if (dropShadow.color != null) {
|
|
@@ -273,7 +273,7 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
|
|
|
273
273
|
accessible == null
|
|
274
274
|
? onPress != null || onLongPress != null
|
|
275
275
|
: accessible,
|
|
276
|
-
default: accessible,
|
|
276
|
+
default: accessible !== false, // Win32
|
|
277
277
|
});
|
|
278
278
|
|
|
279
279
|
let nativeText = null;
|
|
@@ -49,12 +49,6 @@ const textViewConfig = {
|
|
|
49
49
|
dataDetectorType: true,
|
|
50
50
|
android_hyphenationFrequency: true,
|
|
51
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
|
-
}),
|
|
58
52
|
},
|
|
59
53
|
directEventTypes: {
|
|
60
54
|
topTextLayout: {
|
|
@@ -83,12 +83,6 @@ const textViewConfig = {
|
|
|
83
83
|
textStyle: true,
|
|
84
84
|
tooltip: true,
|
|
85
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
|
-
}),
|
|
92
86
|
},
|
|
93
87
|
directEventTypes: {
|
|
94
88
|
topTextLayout: {
|
|
@@ -8,100 +8,124 @@
|
|
|
8
8
|
* @flow strict-local
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type {EventSubscription} from '../vendor/emitter/EventEmitter';
|
|
12
|
+
import type {AppearancePreferences, ColorSchemeName} from './NativeAppearance';
|
|
13
|
+
import typeof INativeAppearance from './NativeAppearance';
|
|
14
|
+
|
|
11
15
|
import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
|
|
12
|
-
import
|
|
13
|
-
import EventEmitter, {
|
|
14
|
-
type EventSubscription,
|
|
15
|
-
} from '../vendor/emitter/EventEmitter';
|
|
16
|
+
import EventEmitter from '../vendor/emitter/EventEmitter';
|
|
16
17
|
import {isAsyncDebugging} from './DebugEnvironment';
|
|
17
|
-
import NativeAppearance, {
|
|
18
|
-
type AppearancePreferences,
|
|
19
|
-
type ColorSchemeName,
|
|
20
|
-
} from './NativeAppearance';
|
|
21
18
|
import invariant from 'invariant';
|
|
22
19
|
|
|
23
|
-
type
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}>();
|
|
20
|
+
type Appearance = {
|
|
21
|
+
colorScheme: ?ColorSchemeName,
|
|
22
|
+
};
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
let lazyState: ?{
|
|
25
|
+
+NativeAppearance: INativeAppearance,
|
|
26
|
+
// Cache the color scheme to reduce the cost of reading it between changes.
|
|
27
|
+
// NOTE: If `NativeAppearance` is null, this will always be null.
|
|
28
|
+
appearance: ?Appearance,
|
|
29
|
+
// NOTE: This is non-nullable to make it easier for `onChangedListener` to
|
|
30
|
+
// return a non-nullable `EventSubscription` value. This is not the common
|
|
31
|
+
// path, so we do not have to over-optimize it.
|
|
32
|
+
+eventEmitter: EventEmitter<{change: [Appearance]}>,
|
|
30
33
|
};
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Ensures that all state and listeners are lazily initialized correctly.
|
|
37
|
+
*/
|
|
38
|
+
function getState(): $NonMaybeType<typeof lazyState> {
|
|
39
|
+
if (lazyState != null) {
|
|
40
|
+
return lazyState;
|
|
41
|
+
}
|
|
42
|
+
const eventEmitter = new EventEmitter<{change: [Appearance]}>();
|
|
43
|
+
// NOTE: Avoid initializing `NativeAppearance` until it is actually used.
|
|
44
|
+
const NativeAppearance = require('./NativeAppearance').default;
|
|
45
|
+
if (NativeAppearance == null) {
|
|
46
|
+
// Assign `null` to avoid re-initializing on subsequent invocations.
|
|
47
|
+
lazyState = {
|
|
48
|
+
NativeAppearance: null,
|
|
49
|
+
appearance: null,
|
|
50
|
+
eventEmitter,
|
|
51
|
+
};
|
|
52
|
+
} else {
|
|
53
|
+
const state: $NonMaybeType<typeof lazyState> = {
|
|
54
|
+
NativeAppearance,
|
|
55
|
+
appearance: null,
|
|
56
|
+
eventEmitter,
|
|
57
|
+
};
|
|
58
|
+
new NativeEventEmitter<{
|
|
59
|
+
appearanceChanged: [AppearancePreferences],
|
|
60
|
+
}>(NativeAppearance).addListener('appearanceChanged', newAppearance => {
|
|
61
|
+
state.appearance = {
|
|
62
|
+
colorScheme: toColorScheme(newAppearance.colorScheme),
|
|
63
|
+
};
|
|
64
|
+
eventEmitter.emit('change', state.appearance);
|
|
65
|
+
});
|
|
66
|
+
lazyState = state;
|
|
67
|
+
}
|
|
68
|
+
return lazyState;
|
|
52
69
|
}
|
|
53
70
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
getColorScheme(): ?ColorSchemeName {
|
|
66
|
-
if (__DEV__) {
|
|
67
|
-
if (isAsyncDebugging) {
|
|
68
|
-
// Hard code light theme when using the async debugger as
|
|
69
|
-
// sync calls aren't supported
|
|
70
|
-
return 'light';
|
|
71
|
-
}
|
|
71
|
+
/**
|
|
72
|
+
* Returns the current color scheme preference. This value may change, so the
|
|
73
|
+
* value should not be cached without either listening to changes or using
|
|
74
|
+
* the `useColorScheme` hook.
|
|
75
|
+
*/
|
|
76
|
+
export function getColorScheme(): ?ColorSchemeName {
|
|
77
|
+
if (__DEV__) {
|
|
78
|
+
if (isAsyncDebugging) {
|
|
79
|
+
// Hard code light theme when using the async debugger as
|
|
80
|
+
// sync calls aren't supported
|
|
81
|
+
return 'light';
|
|
72
82
|
}
|
|
83
|
+
}
|
|
84
|
+
let colorScheme = null;
|
|
85
|
+
const state = getState();
|
|
86
|
+
const {NativeAppearance} = state;
|
|
87
|
+
if (NativeAppearance != null) {
|
|
88
|
+
if (state.appearance == null) {
|
|
89
|
+
// Lazily initialize `state.appearance`. This should only
|
|
90
|
+
// happen once because we never reassign a null value to it.
|
|
91
|
+
state.appearance = {
|
|
92
|
+
colorScheme: toColorScheme(NativeAppearance.getColorScheme()),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
colorScheme = state.appearance.colorScheme;
|
|
96
|
+
}
|
|
97
|
+
return colorScheme;
|
|
98
|
+
}
|
|
73
99
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return nativeColorScheme;
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
setColorScheme(colorScheme: ?ColorSchemeName): void {
|
|
89
|
-
const nativeColorScheme = colorScheme == null ? 'unspecified' : colorScheme;
|
|
90
|
-
|
|
91
|
-
invariant(
|
|
92
|
-
colorScheme === 'dark' || colorScheme === 'light' || colorScheme == null,
|
|
93
|
-
"Unrecognized color scheme. Did you mean 'dark', 'light' or null?",
|
|
94
|
-
);
|
|
100
|
+
/**
|
|
101
|
+
* Updates the current color scheme to the supplied value.
|
|
102
|
+
*/
|
|
103
|
+
export function setColorScheme(colorScheme: ?ColorSchemeName): void {
|
|
104
|
+
const state = getState();
|
|
105
|
+
const {NativeAppearance} = state;
|
|
106
|
+
if (NativeAppearance != null) {
|
|
107
|
+
NativeAppearance.setColorScheme(colorScheme ?? 'unspecified');
|
|
108
|
+
state.appearance = {colorScheme};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
95
111
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Add an event handler that is fired when appearance preferences change.
|
|
114
|
+
*/
|
|
115
|
+
export function addChangeListener(
|
|
116
|
+
listener: ({colorScheme: ?ColorSchemeName}) => void,
|
|
117
|
+
): EventSubscription {
|
|
118
|
+
const {eventEmitter} = getState();
|
|
119
|
+
return eventEmitter.addListener('change', listener);
|
|
120
|
+
}
|
|
100
121
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
122
|
+
/**
|
|
123
|
+
* TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union
|
|
124
|
+
*/
|
|
125
|
+
function toColorScheme(colorScheme: ?string): ?ColorSchemeName {
|
|
126
|
+
invariant(
|
|
127
|
+
colorScheme === 'dark' || colorScheme === 'light' || colorScheme == null,
|
|
128
|
+
"Unrecognized color scheme. Did you mean 'dark', 'light' or null?",
|
|
129
|
+
);
|
|
130
|
+
return colorScheme;
|
|
131
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import processColor from '../StyleSheet/processColor';
|
|
12
|
-
import
|
|
12
|
+
import {getColorScheme} from './Appearance';
|
|
13
13
|
import NativeDevLoadingView from './NativeDevLoadingView';
|
|
14
14
|
|
|
15
15
|
const COLOR_SCHEME = {
|
|
@@ -39,9 +39,7 @@ module.exports = {
|
|
|
39
39
|
showMessage(message: string, type: 'load' | 'refresh') {
|
|
40
40
|
if (NativeDevLoadingView) {
|
|
41
41
|
const colorScheme =
|
|
42
|
-
|
|
43
|
-
? COLOR_SCHEME.dark
|
|
44
|
-
: COLOR_SCHEME.default;
|
|
42
|
+
getColorScheme() === 'dark' ? COLOR_SCHEME.dark : COLOR_SCHEME.default;
|
|
45
43
|
|
|
46
44
|
const colorSet = colorScheme[type];
|
|
47
45
|
|
|
@@ -15,11 +15,8 @@ import type {
|
|
|
15
15
|
Timespan,
|
|
16
16
|
} from './IPerformanceLogger';
|
|
17
17
|
|
|
18
|
-
import * as Systrace from '../Performance/Systrace';
|
|
19
18
|
import infoLog from './infoLog';
|
|
20
19
|
|
|
21
|
-
const _cookies: {[key: string]: number, ...} = {};
|
|
22
|
-
|
|
23
20
|
const PRINT_TO_CONSOLE: false = false; // Type as false to prevent accidentally committing `true`;
|
|
24
21
|
|
|
25
22
|
export const getCurrentTimestamp: () => number =
|
|
@@ -233,7 +230,6 @@ class PerformanceLogger implements IPerformanceLogger {
|
|
|
233
230
|
startTime: timestamp,
|
|
234
231
|
startExtras: extras,
|
|
235
232
|
};
|
|
236
|
-
_cookies[key] = Systrace.beginAsyncEvent(key);
|
|
237
233
|
if (PRINT_TO_CONSOLE) {
|
|
238
234
|
infoLog('PerformanceLogger.js', 'start: ' + key);
|
|
239
235
|
}
|
|
@@ -277,11 +273,6 @@ class PerformanceLogger implements IPerformanceLogger {
|
|
|
277
273
|
if (PRINT_TO_CONSOLE) {
|
|
278
274
|
infoLog('PerformanceLogger.js', 'end: ' + key);
|
|
279
275
|
}
|
|
280
|
-
|
|
281
|
-
if (_cookies[key] != null) {
|
|
282
|
-
Systrace.endAsyncEvent(key, _cookies[key]);
|
|
283
|
-
delete _cookies[key];
|
|
284
|
-
}
|
|
285
276
|
}
|
|
286
277
|
}
|
|
287
278
|
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export default function stringifyViewConfig(viewConfig: any): string {
|
|
12
|
+
return JSON.stringify(
|
|
13
|
+
viewConfig,
|
|
14
|
+
(key, val) => {
|
|
15
|
+
if (typeof val === 'function') {
|
|
16
|
+
return `ƒ ${val.name}`;
|
|
17
|
+
}
|
|
18
|
+
return val;
|
|
19
|
+
},
|
|
20
|
+
2,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
|
|
13
13
|
import type {ColorSchemeName} from './NativeAppearance';
|
|
14
14
|
|
|
15
|
-
import
|
|
15
|
+
import {addChangeListener, getColorScheme} from './Appearance';
|
|
16
16
|
import {useSyncExternalStore} from 'react';
|
|
17
17
|
|
|
18
18
|
const subscribe = (onStoreChange: () => void) => {
|
|
19
|
-
const appearanceSubscription =
|
|
19
|
+
const appearanceSubscription = addChangeListener(onStoreChange);
|
|
20
20
|
return () => appearanceSubscription.remove();
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
export default function useColorScheme(): ?ColorSchemeName {
|
|
24
|
-
return useSyncExternalStore(subscribe,
|
|
24
|
+
return useSyncExternalStore(subscribe, getColorScheme);
|
|
25
25
|
}
|
|
@@ -27,7 +27,7 @@ let rejectionTrackingOptions: $NonMaybeType<Parameters<enable>[0]> = {
|
|
|
27
27
|
stack = error.stack;
|
|
28
28
|
} else {
|
|
29
29
|
try {
|
|
30
|
-
message = require('pretty-format')(rejection);
|
|
30
|
+
message = require('pretty-format').format(rejection);
|
|
31
31
|
} catch {
|
|
32
32
|
message =
|
|
33
33
|
typeof rejection === 'string'
|
package/index.js
CHANGED
|
@@ -82,7 +82,7 @@ import typeof StyleSheet from './Libraries/StyleSheet/StyleSheet';
|
|
|
82
82
|
import typeof Text from './Libraries/Text/Text';
|
|
83
83
|
import typeof * as TurboModuleRegistry from './Libraries/TurboModule/TurboModuleRegistry';
|
|
84
84
|
import typeof UTFSequence from './Libraries/UTFSequence';
|
|
85
|
-
import typeof Appearance from './Libraries/Utilities/Appearance';
|
|
85
|
+
import typeof * as Appearance from './Libraries/Utilities/Appearance';
|
|
86
86
|
import typeof BackHandler from './Libraries/Utilities/BackHandler';
|
|
87
87
|
import typeof DeviceInfo from './Libraries/Utilities/DeviceInfo';
|
|
88
88
|
import typeof DevSettings from './Libraries/Utilities/DevSettings';
|
package/index.win32.js
CHANGED
|
@@ -82,7 +82,7 @@ import typeof StyleSheet from './Libraries/StyleSheet/StyleSheet';
|
|
|
82
82
|
import typeof Text from './Libraries/Text/Text';
|
|
83
83
|
import typeof * as TurboModuleRegistry from './Libraries/TurboModule/TurboModuleRegistry';
|
|
84
84
|
import typeof UTFSequence from './Libraries/UTFSequence';
|
|
85
|
-
import typeof Appearance from './Libraries/Utilities/Appearance';
|
|
85
|
+
import typeof * as Appearance from './Libraries/Utilities/Appearance';
|
|
86
86
|
import typeof BackHandler from './Libraries/Utilities/BackHandler';
|
|
87
87
|
import typeof DeviceInfo from './Libraries/Utilities/DeviceInfo';
|
|
88
88
|
import typeof DevSettings from './Libraries/Utilities/DevSettings';
|