@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.
Files changed (51) hide show
  1. package/.flowconfig +4 -3
  2. package/CHANGELOG.json +37 -1
  3. package/CHANGELOG.md +21 -4
  4. package/Libraries/Animated/nodes/AnimatedObject.js +2 -5
  5. package/Libraries/Animated/nodes/AnimatedProps.js +2 -0
  6. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +0 -3
  7. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +0 -3
  8. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +0 -3
  9. package/Libraries/Components/TextInput/TextInput.js +20 -24
  10. package/Libraries/Components/TextInput/TextInput.win32.js +20 -24
  11. package/Libraries/Components/View/ViewNativeComponent.js +0 -7
  12. package/Libraries/Core/ReactNativeVersion.js +1 -1
  13. package/Libraries/Image/ImageViewNativeComponent.js +0 -3
  14. package/Libraries/Lists/SectionListModern.js +2 -2
  15. package/Libraries/LogBox/Data/LogBoxData.js +8 -14
  16. package/Libraries/Modal/Modal.js +0 -1
  17. package/Libraries/NativeComponent/BaseViewConfig.android.js +6 -0
  18. package/Libraries/NativeComponent/NativeComponentRegistry.js +13 -20
  19. package/Libraries/NativeComponent/StaticViewConfigValidator.js +0 -21
  20. package/Libraries/ReactNative/RendererImplementation.js +2 -2
  21. package/Libraries/Renderer/shims/ReactNativeTypes.js +9 -4
  22. package/Libraries/StyleSheet/StyleSheetTypes.d.ts +3 -3
  23. package/Libraries/StyleSheet/StyleSheetTypes.js +1 -1
  24. package/Libraries/StyleSheet/processBackgroundImage.js +137 -39
  25. package/Libraries/StyleSheet/processBoxShadow.js +1 -1
  26. package/Libraries/StyleSheet/processFilter.js +9 -5
  27. package/Libraries/Text/Text.win32.js +1 -1
  28. package/Libraries/Text/TextNativeComponent.js +0 -6
  29. package/Libraries/Text/TextNativeComponent.win32.js +0 -6
  30. package/Libraries/Utilities/Appearance.js +108 -84
  31. package/Libraries/Utilities/DevLoadingView.js +2 -4
  32. package/Libraries/Utilities/HMRClient.js +1 -1
  33. package/Libraries/Utilities/createPerformanceLogger.js +0 -9
  34. package/Libraries/Utilities/stringifyViewConfig.js +22 -0
  35. package/Libraries/Utilities/useColorScheme.js +3 -3
  36. package/Libraries/promiseRejectionTrackingOptions.js +1 -1
  37. package/index.js +1 -1
  38. package/index.win32.js +1 -1
  39. package/jest/setup.js +0 -4
  40. package/overrides.json +5 -5
  41. package/package.json +13 -13
  42. package/src/private/featureflags/ReactNativeFeatureFlags.js +27 -6
  43. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +5 -2
  44. package/src/private/fusebox/FuseboxSessionObserver.js +42 -0
  45. package/src/private/specs/modules/NativeAppearance.js +3 -3
  46. package/src/private/webapis/intersectionobserver/IntersectionObserver.js +4 -2
  47. package/src/private/webapis/intersectionobserver/IntersectionObserverManager.js +9 -9
  48. package/src/private/webapis/mutationobserver/MutationObserver.js +4 -2
  49. package/src/private/webapis/mutationobserver/MutationObserverManager.js +19 -10
  50. package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +0 -135
  51. 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 stop = bgImage.colorStops[index];
51
- const processedColor = processColor(stop.color);
52
- let processedPosition: number | null = null;
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
- if (processedColor != null) {
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: processedPosition,
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: processedColorStops,
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, position] = colorStopMatch;
160
+ const [, color, position1, position2] = colorStopMatch;
158
161
  const processedColor = processColor(color.trim().toLowerCase());
159
- if (
160
- processedColor != null &&
161
- (typeof position === 'undefined' || position.endsWith('%'))
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: position ? parseFloat(position) / 100 : null,
180
+ position: null,
166
181
  });
167
- } else {
168
- // If a color or position is invalid, return an empty array and do not apply any gradient. Same as web.
169
- return [];
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: colorStops.map((stop, index, array) => ({
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
- // matches on functions with args like "drop-shadow(1.5)"
48
- const regex = /([\w-]+)\(([^)]+)\)/g;
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 on all whitespaces
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 Platform from '../Utilities/Platform';
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 AppearanceListener = (preferences: AppearancePreferences) => void;
24
- const eventEmitter = new EventEmitter<{
25
- change: [AppearancePreferences],
26
- }>();
20
+ type Appearance = {
21
+ colorScheme: ?ColorSchemeName,
22
+ };
27
23
 
28
- type NativeAppearanceEventDefinitions = {
29
- appearanceChanged: [AppearancePreferences],
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
- if (NativeAppearance) {
33
- const nativeEventEmitter =
34
- new NativeEventEmitter<NativeAppearanceEventDefinitions>(
35
- // T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior
36
- // If you want to use the native module on other platforms, please remove this condition and test its behavior
37
- Platform.OS !== 'ios' ? null : NativeAppearance,
38
- );
39
- nativeEventEmitter.addListener(
40
- 'appearanceChanged',
41
- (newAppearance: AppearancePreferences) => {
42
- const {colorScheme} = newAppearance;
43
- invariant(
44
- colorScheme === 'dark' ||
45
- colorScheme === 'light' ||
46
- colorScheme == null,
47
- "Unrecognized color scheme. Did you mean 'dark' or 'light'?",
48
- );
49
- eventEmitter.emit('change', {colorScheme});
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
- module.exports = {
55
- /**
56
- * Note: Although color scheme is available immediately, it may change at any
57
- * time. Any rendering logic or styles that depend on this should try to call
58
- * this function on every render, rather than caching the value (for example,
59
- * using inline styles rather than setting a value in a `StyleSheet`).
60
- *
61
- * Example: `const colorScheme = Appearance.getColorScheme();`
62
- *
63
- * @returns {?ColorSchemeName} Value for the color scheme preference.
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
- // TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union
75
- const nativeColorScheme: ?string =
76
- NativeAppearance == null
77
- ? null
78
- : NativeAppearance.getColorScheme() || null;
79
- invariant(
80
- nativeColorScheme === 'dark' ||
81
- nativeColorScheme === 'light' ||
82
- nativeColorScheme == null,
83
- "Unrecognized color scheme. Did you mean 'dark' or 'light'?",
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
- if (NativeAppearance != null && NativeAppearance.setColorScheme != null) {
97
- NativeAppearance.setColorScheme(nativeColorScheme);
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
- * Add an event handler that is fired when appearance preferences change.
103
- */
104
- addChangeListener(listener: AppearanceListener): EventSubscription {
105
- return eventEmitter.addListener('change', listener);
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 Appearance from './Appearance';
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
- Appearance.getColorScheme() === 'dark'
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
 
@@ -126,7 +126,7 @@ const HMRClient: HMRClientNativeInterface = {
126
126
  data: data.map(item =>
127
127
  typeof item === 'string'
128
128
  ? item
129
- : prettyFormat(item, {
129
+ : prettyFormat.format(item, {
130
130
  escapeString: true,
131
131
  highlight: true,
132
132
  maxDepth: 3,
@@ -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 Appearance from './Appearance';
15
+ import {addChangeListener, getColorScheme} from './Appearance';
16
16
  import {useSyncExternalStore} from 'react';
17
17
 
18
18
  const subscribe = (onStoreChange: () => void) => {
19
- const appearanceSubscription = Appearance.addChangeListener(onStoreChange);
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, Appearance.getColorScheme);
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';